@atlashub/smartstack-cli 4.47.0 → 4.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.documentation/testing-ba-e2e.md +76 -24
- package/package.json +1 -1
- package/templates/agents/gitflow/init.md +26 -0
- package/templates/skills/apex/references/parallel-execution.md +22 -4
- package/templates/skills/apex/steps/step-00-init.md +38 -0
- package/templates/skills/apex/steps/step-03a-layer0-domain.md +21 -0
- package/templates/skills/apex/steps/step-03b-layer1-seed.md +60 -0
- package/templates/skills/apex/steps/step-03c-layer2-backend.md +124 -13
- package/templates/skills/apex/steps/step-03d-layer3-frontend.md +32 -0
- package/templates/skills/application/references/backend-controller-hierarchy.md +14 -4
- package/templates/skills/business-analyse-design/steps/step-02-wireframes.md +14 -0
- package/templates/skills/business-analyse-develop/references/compact-loop.md +15 -1
- package/templates/skills/business-analyse-develop/references/module-transition.md +10 -0
- package/templates/skills/business-analyse-develop/references/quality-gates.md +91 -1
- package/templates/skills/business-analyse-develop/steps/step-00-init.md +57 -0
- package/templates/skills/business-analyse-develop/steps/step-01-task.md +151 -2
- package/templates/skills/business-analyse-develop/steps/step-02-execute.md +14 -1
- package/templates/skills/business-analyse-develop/steps/step-02-v4-verify.md +22 -2
- package/templates/skills/business-analyse-develop/steps/step-03-commit.md +1 -1
- package/templates/skills/business-analyse-develop/steps/step-04-check.md +4 -1
- package/templates/skills/business-analyse-handoff/references/acceptance-criteria.md +53 -1
- package/templates/skills/business-analyse-handoff/references/handoff-file-templates.md +42 -0
- package/templates/skills/business-analyse-handoff/references/handoff-mappings.md +15 -1
- package/templates/skills/business-analyse-handoff/references/prd-generation.md +100 -0
- package/templates/skills/business-analyse-handoff/steps/step-01-transform.md +27 -1
- package/templates/skills/business-analyse-handoff/steps/step-02-export.md +38 -8
- package/templates/skills/business-analyse-html/html/ba-interactive.html +64 -5
- package/templates/skills/business-analyse-html/html/src/scripts/02-navigation.js +13 -1
- package/templates/skills/business-analyse-html/html/src/scripts/05-render-specs.js +10 -1
- package/templates/skills/business-analyse-html/html/src/scripts/06-render-mockups.js +1 -1
- package/templates/skills/business-analyse-html/html/src/styles/03-navigation.css +2 -2
- package/templates/skills/business-analyse-html/html/src/styles/05-modules.css +38 -0
- package/templates/skills/business-analyse-html/steps/step-02-build-data.md +26 -5
- package/templates/skills/controller/references/mcp-scaffold-workflow.md +8 -4
- package/templates/skills/controller/steps/step-05-validate.md +2 -2
- package/templates/skills/controller/templates.md +4 -3
- package/templates/skills/feature-full/steps/step-01-implementation.md +18 -5
|
@@ -51,6 +51,12 @@ These verify data that `/business-analyse-handoff` step-01 generates:
|
|
|
51
51
|
| AC-09 | BR-to-code mapping present | 1 | `handoff.brToCodeMapping[]` | YES |
|
|
52
52
|
| AC-10 | API endpoint summary present | 1 | `handoff.apiEndpointSummary[]` | YES |
|
|
53
53
|
| AC-11 | SeedData entries have category | ALL | `handoff.filesToCreate.seedData[].category` | YES |
|
|
54
|
+
| AC-12 | `specificationFiles` present with 5 paths | 5 | `handoff.specificationFiles` | YES |
|
|
55
|
+
| AC-13 | Companion entities file exists and count matches source | match | `.ralph/prd-{module}.entities.json` | YES |
|
|
56
|
+
| AC-14 | Companion rules file exists and count matches source | match | `.ralph/prd-{module}.rules.json` | YES |
|
|
57
|
+
| AC-15 | Companion usecases file exists and count matches source | match | `.ralph/prd-{module}.usecases.json` | YES |
|
|
58
|
+
| AC-16 | Companion screens file exists (if screens.json exists) | exists | `.ralph/prd-{module}.screens.json` | YES |
|
|
59
|
+
| AC-17 | Each `brToCodeMapping[].statement` non-empty | ALL | `handoff.brToCodeMapping[].statement` | YES |
|
|
54
60
|
|
|
55
61
|
---
|
|
56
62
|
|
|
@@ -240,11 +246,51 @@ if (noCat.length > 0) {
|
|
|
240
246
|
console.error('FAIL: AC-11: ' + noCat.length + ' seedData entries missing category field');
|
|
241
247
|
}
|
|
242
248
|
|
|
249
|
+
// AC-12: specificationFiles present with 5 paths
|
|
250
|
+
const specFiles = handoff.specificationFiles || {};
|
|
251
|
+
const specKeys = ['entities', 'rules', 'usecases', 'screens', 'permissions'];
|
|
252
|
+
const missingSpecs = specKeys.filter(k => !specFiles[k]);
|
|
253
|
+
if (missingSpecs.length > 0) {
|
|
254
|
+
fails.push('AC-12: specificationFiles missing keys: ' + missingSpecs.join(', '));
|
|
255
|
+
console.error('FAIL: AC-12: specificationFiles missing keys: ' + missingSpecs.join(', '));
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// AC-13 to AC-16: Companion files exist and counts match
|
|
259
|
+
const ralphDir = path.dirname(process.argv[1]);
|
|
260
|
+
const companionChecks = [
|
|
261
|
+
{ ac: 'AC-13', key: 'entities', arrayKey: 'entities' },
|
|
262
|
+
{ ac: 'AC-14', key: 'rules', arrayKey: 'rules' },
|
|
263
|
+
{ ac: 'AC-15', key: 'usecases', arrayKey: 'useCases' },
|
|
264
|
+
{ ac: 'AC-16', key: 'screens', arrayKey: 'screens' }
|
|
265
|
+
];
|
|
266
|
+
for (const check of companionChecks) {
|
|
267
|
+
const companionPath = specFiles[check.key] ? path.join(ralphDir, specFiles[check.key]) : null;
|
|
268
|
+
if (companionPath && fs.existsSync(companionPath)) {
|
|
269
|
+
const companionData = JSON.parse(fs.readFileSync(companionPath, 'utf-8'));
|
|
270
|
+
const arr = companionData[check.arrayKey] || companionData[check.arrayKey.toLowerCase()] || [];
|
|
271
|
+
if (arr.length === 0 && check.ac !== 'AC-16') {
|
|
272
|
+
fails.push(check.ac + ': companion ' + check.key + ' file is empty');
|
|
273
|
+
console.error('FAIL: ' + check.ac + ': companion ' + check.key + ' file has 0 entries');
|
|
274
|
+
}
|
|
275
|
+
} else if (companionPath) {
|
|
276
|
+
fails.push(check.ac + ': companion file missing: ' + specFiles[check.key]);
|
|
277
|
+
console.error('FAIL: ' + check.ac + ': companion file not found: ' + specFiles[check.key]);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// AC-17: Each brToCodeMapping[].statement non-empty
|
|
282
|
+
const brMapping = handoff.brToCodeMapping || [];
|
|
283
|
+
const emptyStatements = brMapping.filter(br => !br.statement || br.statement.trim() === '');
|
|
284
|
+
if (emptyStatements.length > 0) {
|
|
285
|
+
fails.push('AC-17: ' + emptyStatements.length + ' BRs with empty statement');
|
|
286
|
+
console.error('FAIL: AC-17: ' + emptyStatements.length + ' brToCodeMapping entries have empty statement: ' + emptyStatements.slice(0, 3).map(b => b.ruleId).join(', '));
|
|
287
|
+
}
|
|
288
|
+
|
|
243
289
|
if (fails.length > 0) {
|
|
244
290
|
console.error('\\nBLOCKING: ' + fails.length + ' output acceptance criteria FAILED');
|
|
245
291
|
process.exit(1);
|
|
246
292
|
}
|
|
247
|
-
console.log('PASS: All output acceptance criteria met (AC-08 to AC-
|
|
293
|
+
console.log('PASS: All output acceptance criteria met (AC-08 to AC-17)');
|
|
248
294
|
" "$MODULE_JSON"
|
|
249
295
|
```
|
|
250
296
|
|
|
@@ -264,3 +310,9 @@ console.log('PASS: All output acceptance criteria met (AC-08 to AC-11)');
|
|
|
264
310
|
| AC-09 | Re-run `/business-analyse-handoff` step-01 transform (BR mapping) |
|
|
265
311
|
| AC-10 | Re-run `/business-analyse-handoff` step-01 transform (API endpoints) |
|
|
266
312
|
| AC-11 | Re-run `/business-analyse-handoff` step-01 transform (seedData categories) |
|
|
313
|
+
| AC-12 | Re-run `/business-analyse-handoff` step-01 transform (specificationFiles missing) |
|
|
314
|
+
| AC-13 | Re-run `/business-analyse-handoff` step-01 transform (entities companion missing/empty) |
|
|
315
|
+
| AC-14 | Re-run `/business-analyse-handoff` step-01 transform (rules companion missing/empty) |
|
|
316
|
+
| AC-15 | Re-run `/business-analyse-handoff` step-01 transform (usecases companion missing/empty) |
|
|
317
|
+
| AC-16 | Re-run `/business-analyse-handoff` step-01 transform (screens companion missing) |
|
|
318
|
+
| AC-17 | Re-run `/business-analyse-handoff` step-01 transform (BR statements empty — copy from rules.json) |
|
|
@@ -153,3 +153,45 @@ From `screens.json > screens[]` and `usecases.json > useCases[]`:
|
|
|
153
153
|
|
|
154
154
|
Include: Technical documentation data, API specification files, user guides.
|
|
155
155
|
This category can be an empty array `[]` if no documentation is planned at this stage. It will be populated by the `/documentation` skill after `/business-analyse-develop` completes.
|
|
156
|
+
|
|
157
|
+
## 4.9 Specification Files (Companion Files)
|
|
158
|
+
|
|
159
|
+
> **Purpose:** Enable `/apex` and `/business-analyse-develop` to load full BA specifications per layer, avoiding monolithic context loading.
|
|
160
|
+
|
|
161
|
+
Each PRD MUST include a `specificationFiles` object referencing 5 companion files:
|
|
162
|
+
|
|
163
|
+
```json
|
|
164
|
+
"specificationFiles": {
|
|
165
|
+
"entities": "prd-{moduleCode}.entities.json",
|
|
166
|
+
"rules": "prd-{moduleCode}.rules.json",
|
|
167
|
+
"usecases": "prd-{moduleCode}.usecases.json",
|
|
168
|
+
"screens": "prd-{moduleCode}.screens.json",
|
|
169
|
+
"permissions": "prd-{moduleCode}.permissions.json"
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Naming Convention
|
|
174
|
+
|
|
175
|
+
`prd-{moduleCode}.{section}.json` — all files colocated in `.ralph/` alongside the PRD.
|
|
176
|
+
|
|
177
|
+
| File | Source | Content |
|
|
178
|
+
|------|--------|---------|
|
|
179
|
+
| `prd-{moduleCode}.entities.json` | `{moduleDir}/entities.json` | VERBATIM copy |
|
|
180
|
+
| `prd-{moduleCode}.rules.json` | `{moduleDir}/rules.json` | VERBATIM copy |
|
|
181
|
+
| `prd-{moduleCode}.usecases.json` | `{moduleDir}/usecases.json` | VERBATIM copy |
|
|
182
|
+
| `prd-{moduleCode}.screens.json` | `{moduleDir}/screens.json` | VERBATIM copy |
|
|
183
|
+
| `prd-{moduleCode}.permissions.json` | `{moduleDir}/permissions.json` | VERBATIM copy |
|
|
184
|
+
|
|
185
|
+
### Rules
|
|
186
|
+
|
|
187
|
+
- **VERBATIM copy:** Each companion file is a 1:1 copy of the BA source file. Zero transformation, zero filtering.
|
|
188
|
+
- **Colocated:** All companion files live in `.ralph/` alongside the PRD file.
|
|
189
|
+
- **Mandatory:** All 5 companion files MUST be generated for every module PRD.
|
|
190
|
+
- **Layer loading:** `/apex` loads only the companion files needed per layer (see loading plan below).
|
|
191
|
+
|
|
192
|
+
| Layer | Files loaded | Estimated context |
|
|
193
|
+
|-------|-------------|-------------------|
|
|
194
|
+
| Layer 0 (domain) | `entities.json` | ~200-400 lines |
|
|
195
|
+
| Layer 1 (seed) | `entities.json` + `permissions.json` | ~300-500 lines |
|
|
196
|
+
| Layer 2 (backend) | `rules.json` + `usecases.json` | ~300-600 lines |
|
|
197
|
+
| Layer 3 (frontend) | `screens.json` + `usecases.json` | ~300-500 lines |
|
|
@@ -12,6 +12,13 @@ Generate complete mapping for each BR:
|
|
|
12
12
|
{
|
|
13
13
|
"ruleId": "BR-VAL-001",
|
|
14
14
|
"title": "Order total must equal sum of item prices",
|
|
15
|
+
"statement": "The order total amount must equal the sum of all order item prices multiplied by their quantities",
|
|
16
|
+
"example": "Order with 3 items at $10, $20, $30 → total must be $60. If total = $50 → validation error",
|
|
17
|
+
"formula": null,
|
|
18
|
+
"conditions": [],
|
|
19
|
+
"entities": ["Order", "OrderItem"],
|
|
20
|
+
"category": "validation",
|
|
21
|
+
"sectionCode": "orders",
|
|
15
22
|
"module": "{moduleCode}",
|
|
16
23
|
"severity": "critical",
|
|
17
24
|
"implementationPoints": [
|
|
@@ -27,7 +34,14 @@ Generate complete mapping for each BR:
|
|
|
27
34
|
|
|
28
35
|
For each BR include:
|
|
29
36
|
- **ruleId**: Reference to `rules.json > rules[].id`
|
|
30
|
-
- **title**:
|
|
37
|
+
- **title**: Short descriptive title
|
|
38
|
+
- **statement**: VERBATIM copy of `rules.json > rules[].statement` — the full rule text, NOT a paraphrase
|
|
39
|
+
- **example**: VERBATIM copy of `rules.json > rules[].example` — concrete example illustrating the rule (null if absent)
|
|
40
|
+
- **formula**: VERBATIM copy of `rules.json > rules[].formula` — formula for BR-CALC-* rules (null if absent)
|
|
41
|
+
- **conditions**: VERBATIM copy of `rules.json > rules[].conditions[]` — conditions of applicability (empty array if absent)
|
|
42
|
+
- **entities**: Array of entity names this rule applies to (from `rules.json > rules[].entities[]` or inferred from rule context)
|
|
43
|
+
- **category**: Rule category from `rules.json > rules[].category` — one of: validation, calculation, workflow, security, data
|
|
44
|
+
- **sectionCode**: Section this rule belongs to (from `rules.json > rules[].sectionCode` or inferred)
|
|
31
45
|
- **module**: Which module it belongs to
|
|
32
46
|
- **severity**: From `rule.severity` (blocking, info, etc.) mapped to "critical", "high", "medium", "low"
|
|
33
47
|
- **implementationPoints**: Array of {layer, component, method, implementation}
|
|
@@ -80,6 +80,47 @@ ss business-analyse-handoff --feature {path} --output .ralph/prd-{moduleCode}.js
|
|
|
80
80
|
|
|
81
81
|
---
|
|
82
82
|
|
|
83
|
+
### 2b. PRD v4.0 Structure (spec-oriented)
|
|
84
|
+
|
|
85
|
+
> **v4 PRDs are generated with `--v4` flag.** They use `expectedFiles` instead of `implementation.filesToCreate`.
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"$version": "4.0.0",
|
|
90
|
+
"objectives": [
|
|
91
|
+
{ "description": "...", "acceptanceCriteria": ["..."] }
|
|
92
|
+
],
|
|
93
|
+
"expectedFiles": {
|
|
94
|
+
"domain": [...],
|
|
95
|
+
"application": [...],
|
|
96
|
+
"infrastructure": [...],
|
|
97
|
+
"api": [...],
|
|
98
|
+
"frontend": [...],
|
|
99
|
+
"seedData": [...],
|
|
100
|
+
"tests": [...],
|
|
101
|
+
"documentation": [...]
|
|
102
|
+
},
|
|
103
|
+
"gates": { /* declarative quality gate definitions */ }
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Key differences from v3:**
|
|
108
|
+
|
|
109
|
+
| Aspect | v3 (`$version: "3.0.0"`) | v4 (`$version: "4.0.0"`) |
|
|
110
|
+
|--------|--------------------------|--------------------------|
|
|
111
|
+
| File manifest | `implementation.filesToCreate` | `expectedFiles` (root level) |
|
|
112
|
+
| Task model | `tasks[]` (pre-computed) | `objectives[]` (goal-oriented) |
|
|
113
|
+
| Execution | Batch iterations (compact-loop) | Continuous (compaction-enabled) |
|
|
114
|
+
|
|
115
|
+
**Consumer code must handle both:**
|
|
116
|
+
```javascript
|
|
117
|
+
const fileManifest = prd.$version === '4.0.0'
|
|
118
|
+
? prd.expectedFiles
|
|
119
|
+
: prd.implementation?.filesToCreate;
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
83
124
|
### 3. Eight Categories (MANDATORY)
|
|
84
125
|
|
|
85
126
|
All PRD files MUST include these 8 categories under `implementation.filesToCreate`:
|
|
@@ -167,6 +208,64 @@ Each file entry in a category array must have:
|
|
|
167
208
|
|
|
168
209
|
---
|
|
169
210
|
|
|
211
|
+
### 6. Specification Files (MANDATORY)
|
|
212
|
+
|
|
213
|
+
Each PRD MUST include a `specificationFiles` object and 5 companion files in `.ralph/`:
|
|
214
|
+
|
|
215
|
+
```json
|
|
216
|
+
{
|
|
217
|
+
"$version": "3.0.0",
|
|
218
|
+
"implementation": { "filesToCreate": { /* 8 categories */ } },
|
|
219
|
+
"brToCodeMapping": [ /* enriched with statement, example, formula */ ],
|
|
220
|
+
"apiEndpointSummary": [ /* ... */ ],
|
|
221
|
+
"specificationFiles": {
|
|
222
|
+
"entities": "prd-{moduleCode}.entities.json",
|
|
223
|
+
"rules": "prd-{moduleCode}.rules.json",
|
|
224
|
+
"usecases": "prd-{moduleCode}.usecases.json",
|
|
225
|
+
"screens": "prd-{moduleCode}.screens.json",
|
|
226
|
+
"permissions": "prd-{moduleCode}.permissions.json"
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**Companion files** are VERBATIM copies of BA source files, colocated in `.ralph/`:
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
.ralph/
|
|
235
|
+
prd-Employees.json # PRD manifest (compact)
|
|
236
|
+
prd-Employees.entities.json # VERBATIM copy of entities.json
|
|
237
|
+
prd-Employees.rules.json # VERBATIM copy of rules.json
|
|
238
|
+
prd-Employees.usecases.json # VERBATIM copy of usecases.json
|
|
239
|
+
prd-Employees.screens.json # VERBATIM copy of screens.json
|
|
240
|
+
prd-Employees.permissions.json # VERBATIM copy of permissions.json
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
**Validation:**
|
|
244
|
+
```javascript
|
|
245
|
+
const specFiles = prd.specificationFiles;
|
|
246
|
+
if (!specFiles) {
|
|
247
|
+
BLOCKING_ERROR('specificationFiles missing from PRD');
|
|
248
|
+
}
|
|
249
|
+
const specKeys = ['entities', 'rules', 'usecases', 'screens', 'permissions'];
|
|
250
|
+
for (const key of specKeys) {
|
|
251
|
+
if (!specFiles[key]) {
|
|
252
|
+
BLOCKING_ERROR(`specificationFiles.${key} missing`);
|
|
253
|
+
}
|
|
254
|
+
const filePath = path.join('.ralph', specFiles[key]);
|
|
255
|
+
if (!fs.existsSync(filePath)) {
|
|
256
|
+
BLOCKING_ERROR(`Companion file not found: ${filePath}`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**Why companion files matter:**
|
|
262
|
+
- `/apex` loads only the specs needed per layer (entities for L0, rules+usecases for L2, screens for L3)
|
|
263
|
+
- Context per layer is ~200-500 lines instead of ~2000 lines monolithic
|
|
264
|
+
- Zero risk of specs being lost at the bottom of a large context window
|
|
265
|
+
- Full BA detail available for oneshot generation (attributes, formulas, screen columns)
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
170
269
|
## Validation Checklist
|
|
171
270
|
|
|
172
271
|
Use this checklist when validating PRD files:
|
|
@@ -178,6 +277,7 @@ Use this checklist when validating PRD files:
|
|
|
178
277
|
| **Categories** | All 8 categories present | PASS/FAIL |
|
|
179
278
|
| **File Counts** | PRD counts match index.json handoff.filesToCreate | PASS/FAIL |
|
|
180
279
|
| **File Schemas** | All files have path, type, module | PASS/FAIL |
|
|
280
|
+
| **Spec Files** | `specificationFiles` present with 5 paths, all companion files exist | PASS/FAIL |
|
|
181
281
|
|
|
182
282
|
**All checks must PASS before proceeding to /business-analyse-develop**
|
|
183
283
|
|
|
@@ -151,13 +151,39 @@ Write via ba-writer.enrichModuleHandoff with the complete handoff payload:
|
|
|
151
151
|
- totalFiles, totalTasks, handedOffAt (ISO timestamp)
|
|
152
152
|
- featureDescription: {featureDescription}
|
|
153
153
|
|
|
154
|
+
### Specification Files (MANDATORY)
|
|
155
|
+
After writing the handoff data, ALSO write 5 companion files:
|
|
156
|
+
1. `.ralph/prd-{moduleCode}.entities.json` = VERBATIM copy of `{moduleDir}/entities.json`
|
|
157
|
+
2. `.ralph/prd-{moduleCode}.rules.json` = VERBATIM copy of `{moduleDir}/rules.json`
|
|
158
|
+
3. `.ralph/prd-{moduleCode}.usecases.json` = VERBATIM copy of `{moduleDir}/usecases.json`
|
|
159
|
+
4. `.ralph/prd-{moduleCode}.screens.json` = VERBATIM copy of `{moduleDir}/screens.json`
|
|
160
|
+
5. `.ralph/prd-{moduleCode}.permissions.json` = VERBATIM copy of `{moduleDir}/permissions.json`
|
|
161
|
+
|
|
162
|
+
Add `specificationFiles` to the PRD referencing these files (relative names, all in `.ralph/`):
|
|
163
|
+
```json
|
|
164
|
+
"specificationFiles": {
|
|
165
|
+
"entities": "prd-{moduleCode}.entities.json",
|
|
166
|
+
"rules": "prd-{moduleCode}.rules.json",
|
|
167
|
+
"usecases": "prd-{moduleCode}.usecases.json",
|
|
168
|
+
"screens": "prd-{moduleCode}.screens.json",
|
|
169
|
+
"permissions": "prd-{moduleCode}.permissions.json"
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
154
173
|
### POST-CHECK (BLOCKING)
|
|
155
174
|
After writing, verify:
|
|
156
175
|
1. Handoff not empty
|
|
157
176
|
2. All 8 categories present
|
|
158
177
|
3. brToCodeMapping non-empty
|
|
159
178
|
4. Section resources have entity field
|
|
160
|
-
|
|
179
|
+
5. SeedData contains CORE entries (NavigationModuleSeedData, NavigationSectionSeedData if sections exist, PermissionsSeedData, RolesSeedData)
|
|
180
|
+
6. For FIRST module only: SeedData contains APP-LEVEL CORE entries (NavigationApplicationSeedData, ApplicationRolesSeedData)
|
|
181
|
+
7. All 5 companion files exist in `.ralph/` and are non-empty
|
|
182
|
+
8. `specificationFiles` present in the PRD with all 5 paths
|
|
183
|
+
9. Entity count in companion matches source: `prd-{moduleCode}.entities.json` entities[] count = `{moduleDir}/entities.json` entities[] count
|
|
184
|
+
10. BR count in companion matches source: `prd-{moduleCode}.rules.json` rules[] count = `{moduleDir}/rules.json` rules[] count
|
|
185
|
+
11. Each `brToCodeMapping[].statement` is non-empty (not just a title paraphrase)
|
|
186
|
+
Display: "POST-CHECK PASS: {moduleCode} -- 8 categories, {brCount} BRs mapped, {coreCount} core seeds, 5 companion files"
|
|
161
187
|
```
|
|
162
188
|
|
|
163
189
|
### 3. Display Progress
|
|
@@ -91,6 +91,26 @@ for (const cat of categories) {
|
|
|
91
91
|
BLOCKING_ERROR(`${cat}: prd=${prdCount} but feature=${featureCount}`);
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
|
+
|
|
95
|
+
// Check 5: Specification files (companion files)
|
|
96
|
+
const specFiles = prd.specificationFiles;
|
|
97
|
+
if (!specFiles) {
|
|
98
|
+
BLOCKING_ERROR("specificationFiles missing from PRD");
|
|
99
|
+
}
|
|
100
|
+
const specKeys = ['entities', 'rules', 'usecases', 'screens', 'permissions'];
|
|
101
|
+
for (const key of specKeys) {
|
|
102
|
+
if (!specFiles[key]) {
|
|
103
|
+
BLOCKING_ERROR(`specificationFiles.${key} path missing`);
|
|
104
|
+
}
|
|
105
|
+
const companionPath = `.ralph/${specFiles[key]}`;
|
|
106
|
+
if (!fileExists(companionPath)) {
|
|
107
|
+
BLOCKING_ERROR(`Companion file not found: ${companionPath}`);
|
|
108
|
+
}
|
|
109
|
+
const companionSize = fileSize(companionPath);
|
|
110
|
+
if (companionSize < 10) {
|
|
111
|
+
BLOCKING_ERROR(`Companion file empty or too small: ${companionPath} (${companionSize} bytes)`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
94
114
|
```
|
|
95
115
|
|
|
96
116
|
Display verification table showing all 8 categories match between module JSON files and prd.json.
|
|
@@ -99,11 +119,13 @@ Display verification table showing all 8 categories match between module JSON fi
|
|
|
99
119
|
|
|
100
120
|
```json
|
|
101
121
|
{
|
|
102
|
-
"
|
|
103
|
-
{ "
|
|
104
|
-
{ "
|
|
122
|
+
"modules": [
|
|
123
|
+
{ "code": "{code}", "prdFile": ".ralph/prd-{code}.json", "status": "pending", "order": 1, "dependencies": [], "complexity": "simple" },
|
|
124
|
+
{ "code": "{code}", "prdFile": ".ralph/prd-{code}.json", "status": "pending", "order": 2, "dependencies": ["{dep}"], "complexity": "medium" }
|
|
105
125
|
],
|
|
106
|
-
"
|
|
126
|
+
"currentIndex": 0,
|
|
127
|
+
"totalModules": "{count}",
|
|
128
|
+
"completedModules": 0,
|
|
107
129
|
"strategy": "topological"
|
|
108
130
|
}
|
|
109
131
|
```
|
|
@@ -185,10 +207,15 @@ Readiness Scores:
|
|
|
185
207
|
└──────────────┴────────────┴──────────────┘
|
|
186
208
|
|
|
187
209
|
Artifacts generated:
|
|
188
|
-
.ralph/prd-{module}.json
|
|
189
|
-
.ralph/
|
|
190
|
-
.ralph/
|
|
191
|
-
|
|
210
|
+
.ralph/prd-{module}.json — Task breakdown per module
|
|
211
|
+
.ralph/prd-{module}.entities.json — Entity specifications (companion)
|
|
212
|
+
.ralph/prd-{module}.rules.json — Business rules (companion)
|
|
213
|
+
.ralph/prd-{module}.usecases.json — Use cases (companion)
|
|
214
|
+
.ralph/prd-{module}.screens.json — Screen specifications (companion)
|
|
215
|
+
.ralph/prd-{module}.permissions.json — Permissions (companion)
|
|
216
|
+
.ralph/progress.txt — Progression tracker
|
|
217
|
+
.ralph/modules-queue.json — Module execution order (if multi-module)
|
|
218
|
+
docs/index.json — BA manifest (status: handed-off)
|
|
192
219
|
|
|
193
220
|
[NEXT] Development:
|
|
194
221
|
1. Run /business-analyse-develop to begin implementation
|
|
@@ -208,5 +235,8 @@ Artifacts generated:
|
|
|
208
235
|
4. `docs/index.json` updated with correct entry count and status "handed-off"
|
|
209
236
|
5. All PRD files have $version=3.0.0 or 4.0.0, file manifest present, 8 categories
|
|
210
237
|
6. File counts match between PRD and handoff for all categories
|
|
238
|
+
7. For EACH module: 5 companion files exist in `.ralph/` (entities, rules, usecases, screens, permissions)
|
|
239
|
+
8. Each PRD contains `specificationFiles` with all 5 paths
|
|
240
|
+
9. Each companion file is non-empty (>10 bytes)
|
|
211
241
|
|
|
212
242
|
**IF any check fails -> fix before completing.**
|
|
@@ -378,13 +378,13 @@ body {
|
|
|
378
378
|
.nav-icon-section { font-size: 0.5rem; color: var(--accent); }
|
|
379
379
|
.nav-icon-resource { font-size: 0.7rem; color: var(--border-light); }
|
|
380
380
|
.nav-resource-link {
|
|
381
|
-
cursor:
|
|
381
|
+
cursor: pointer;
|
|
382
382
|
font-size: 0.72rem;
|
|
383
383
|
color: var(--text-muted);
|
|
384
384
|
padding-top: 0.2rem;
|
|
385
385
|
padding-bottom: 0.2rem;
|
|
386
386
|
}
|
|
387
|
-
.nav-resource-link:hover { background:
|
|
387
|
+
.nav-resource-link:hover { background: var(--bg-hover); color: var(--accent); }
|
|
388
388
|
.nav-resources { margin-left: 0.5rem; }
|
|
389
389
|
|
|
390
390
|
|
|
@@ -1031,6 +1031,44 @@ body {
|
|
|
1031
1031
|
color: var(--text-muted);
|
|
1032
1032
|
}
|
|
1033
1033
|
|
|
1034
|
+
/* ============================================
|
|
1035
|
+
STRUCTURE LEGEND
|
|
1036
|
+
============================================ */
|
|
1037
|
+
.struct-legend {
|
|
1038
|
+
background: var(--bg-card);
|
|
1039
|
+
border: 1px solid var(--border);
|
|
1040
|
+
border-radius: 10px;
|
|
1041
|
+
padding: 0.75rem 1rem;
|
|
1042
|
+
margin-bottom: 1.25rem;
|
|
1043
|
+
}
|
|
1044
|
+
.struct-legend-title {
|
|
1045
|
+
font-size: 0.8rem;
|
|
1046
|
+
font-weight: 600;
|
|
1047
|
+
color: var(--text-muted);
|
|
1048
|
+
margin-bottom: 0.5rem;
|
|
1049
|
+
}
|
|
1050
|
+
.struct-legend-grid {
|
|
1051
|
+
display: grid;
|
|
1052
|
+
grid-template-columns: 1fr 1fr;
|
|
1053
|
+
gap: 0.4rem 1.5rem;
|
|
1054
|
+
}
|
|
1055
|
+
.struct-legend-item {
|
|
1056
|
+
font-size: 0.78rem;
|
|
1057
|
+
color: var(--text-muted);
|
|
1058
|
+
line-height: 1.4;
|
|
1059
|
+
}
|
|
1060
|
+
.struct-legend-code {
|
|
1061
|
+
display: inline-block;
|
|
1062
|
+
font-weight: 600;
|
|
1063
|
+
color: var(--accent);
|
|
1064
|
+
background: rgba(6,182,212,0.1);
|
|
1065
|
+
padding: 0.05rem 0.4rem;
|
|
1066
|
+
border-radius: 3px;
|
|
1067
|
+
font-size: 0.72rem;
|
|
1068
|
+
margin-right: 0.3rem;
|
|
1069
|
+
font-family: monospace;
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1034
1072
|
/* ============================================
|
|
1035
1073
|
SECTION GROUPS (Hierarchical Mode)
|
|
1036
1074
|
============================================ */
|
|
@@ -2762,7 +2800,7 @@ function renderModuleNavItem(mod) {
|
|
|
2762
2800
|
html += '<div class="nav-children nav-resources">';
|
|
2763
2801
|
resources.forEach(function(res) {
|
|
2764
2802
|
var resName = typeof res === 'string' ? res : (res.code || res.name || '');
|
|
2765
|
-
html += '<a class="nav-item nav-resource-link">';
|
|
2803
|
+
html += '<a class="nav-item nav-resource-link" onclick="showSection(\'module-spec-' + code + '\');switchTab(\'' + code + '\',\'mock\');scrollToMockup(\'' + code + '\',\'' + section.code + '\')">';
|
|
2766
2804
|
html += '<span class="nav-icon nav-icon-resource">•</span> ' + escapeHtml(resName);
|
|
2767
2805
|
html += '</a>';
|
|
2768
2806
|
});
|
|
@@ -2785,6 +2823,18 @@ function renderModuleTabNavItem(code, tabId, label, badge) {
|
|
|
2785
2823
|
'</a>';
|
|
2786
2824
|
}
|
|
2787
2825
|
|
|
2826
|
+
function scrollToMockup(moduleCode, sectionCode) {
|
|
2827
|
+
setTimeout(function() {
|
|
2828
|
+
var el = document.getElementById('screen-' + moduleCode + '-' + sectionCode);
|
|
2829
|
+
if (el) {
|
|
2830
|
+
el.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
2831
|
+
el.style.outline = '2px solid var(--accent)';
|
|
2832
|
+
el.style.borderRadius = '10px';
|
|
2833
|
+
setTimeout(function() { el.style.outline = ''; el.style.borderRadius = ''; }, 2000);
|
|
2834
|
+
}
|
|
2835
|
+
}, 150);
|
|
2836
|
+
}
|
|
2837
|
+
|
|
2788
2838
|
/* ---------- Collapse/Expand ---------- */
|
|
2789
2839
|
|
|
2790
2840
|
function toggleNavGroup(groupId) {
|
|
@@ -3916,7 +3966,16 @@ function renderModuleStructure(code) {
|
|
|
3916
3966
|
'</div>';
|
|
3917
3967
|
}
|
|
3918
3968
|
|
|
3919
|
-
|
|
3969
|
+
var legend = '<div class="struct-legend">' +
|
|
3970
|
+
'<div class="struct-legend-title">ⓘ Types de sections</div>' +
|
|
3971
|
+
'<div class="struct-legend-grid">' +
|
|
3972
|
+
'<div class="struct-legend-item"><span class="struct-legend-code">list</span> Page principale — grille de données avec filtres, tri et actions (créer, exporter)</div>' +
|
|
3973
|
+
'<div class="struct-legend-item"><span class="struct-legend-code">detail</span> Fiche détaillée — affichée au clic sur une ligne, avec onglets (infos, relations, historique)</div>' +
|
|
3974
|
+
'<div class="struct-legend-item"><span class="struct-legend-code">dashboard</span> Tableau de bord — KPIs, graphiques et métriques du module</div>' +
|
|
3975
|
+
'<div class="struct-legend-item"><span class="struct-legend-code">approve</span> Workflow — file de validation avec actions (approuver, rejeter, mettre en attente)</div>' +
|
|
3976
|
+
'</div></div>';
|
|
3977
|
+
|
|
3978
|
+
return legend + sections.map(function(section) {
|
|
3920
3979
|
var resources = section.resources || [];
|
|
3921
3980
|
var sectionUCs = section.useCases || [];
|
|
3922
3981
|
var sectionBRs = section.businessRules || [];
|
|
@@ -4295,7 +4354,7 @@ function renderScreenMockups(code) {
|
|
|
4295
4354
|
|
|
4296
4355
|
return screens.map(function(screen, si) {
|
|
4297
4356
|
var resources = screen.resources || [];
|
|
4298
|
-
return '<div class="screen-section" style="margin-bottom:2rem;">' +
|
|
4357
|
+
return '<div class="screen-section" id="screen-' + code + '-' + screen.sectionCode + '" style="margin-bottom:2rem;">' +
|
|
4299
4358
|
'<h3 style="color:var(--text-bright);font-size:1rem;margin-bottom:1rem;">' +
|
|
4300
4359
|
'<span style="color:var(--accent);">▸</span> ' + escapeHtml(screen.sectionLabel || screen.sectionCode) +
|
|
4301
4360
|
'</h3>' +
|
|
@@ -182,7 +182,7 @@ function renderModuleNavItem(mod) {
|
|
|
182
182
|
html += '<div class="nav-children nav-resources">';
|
|
183
183
|
resources.forEach(function(res) {
|
|
184
184
|
var resName = typeof res === 'string' ? res : (res.code || res.name || '');
|
|
185
|
-
html += '<a class="nav-item nav-resource-link">';
|
|
185
|
+
html += '<a class="nav-item nav-resource-link" onclick="showSection(\'module-spec-' + code + '\');switchTab(\'' + code + '\',\'mock\');scrollToMockup(\'' + code + '\',\'' + section.code + '\')">';
|
|
186
186
|
html += '<span class="nav-icon nav-icon-resource">•</span> ' + escapeHtml(resName);
|
|
187
187
|
html += '</a>';
|
|
188
188
|
});
|
|
@@ -205,6 +205,18 @@ function renderModuleTabNavItem(code, tabId, label, badge) {
|
|
|
205
205
|
'</a>';
|
|
206
206
|
}
|
|
207
207
|
|
|
208
|
+
function scrollToMockup(moduleCode, sectionCode) {
|
|
209
|
+
setTimeout(function() {
|
|
210
|
+
var el = document.getElementById('screen-' + moduleCode + '-' + sectionCode);
|
|
211
|
+
if (el) {
|
|
212
|
+
el.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
213
|
+
el.style.outline = '2px solid var(--accent)';
|
|
214
|
+
el.style.borderRadius = '10px';
|
|
215
|
+
setTimeout(function() { el.style.outline = ''; el.style.borderRadius = ''; }, 2000);
|
|
216
|
+
}
|
|
217
|
+
}, 150);
|
|
218
|
+
}
|
|
219
|
+
|
|
208
220
|
/* ---------- Collapse/Expand ---------- */
|
|
209
221
|
|
|
210
222
|
function toggleNavGroup(groupId) {
|
|
@@ -620,7 +620,16 @@ function renderModuleStructure(code) {
|
|
|
620
620
|
'</div>';
|
|
621
621
|
}
|
|
622
622
|
|
|
623
|
-
|
|
623
|
+
var legend = '<div class="struct-legend">' +
|
|
624
|
+
'<div class="struct-legend-title">ⓘ Types de sections</div>' +
|
|
625
|
+
'<div class="struct-legend-grid">' +
|
|
626
|
+
'<div class="struct-legend-item"><span class="struct-legend-code">list</span> Page principale — grille de données avec filtres, tri et actions (créer, exporter)</div>' +
|
|
627
|
+
'<div class="struct-legend-item"><span class="struct-legend-code">detail</span> Fiche détaillée — affichée au clic sur une ligne, avec onglets (infos, relations, historique)</div>' +
|
|
628
|
+
'<div class="struct-legend-item"><span class="struct-legend-code">dashboard</span> Tableau de bord — KPIs, graphiques et métriques du module</div>' +
|
|
629
|
+
'<div class="struct-legend-item"><span class="struct-legend-code">approve</span> Workflow — file de validation avec actions (approuver, rejeter, mettre en attente)</div>' +
|
|
630
|
+
'</div></div>';
|
|
631
|
+
|
|
632
|
+
return legend + sections.map(function(section) {
|
|
624
633
|
var resources = section.resources || [];
|
|
625
634
|
var sectionUCs = section.useCases || [];
|
|
626
635
|
var sectionBRs = section.businessRules || [];
|
|
@@ -11,7 +11,7 @@ function renderScreenMockups(code) {
|
|
|
11
11
|
|
|
12
12
|
return screens.map(function(screen, si) {
|
|
13
13
|
var resources = screen.resources || [];
|
|
14
|
-
return '<div class="screen-section" style="margin-bottom:2rem;">' +
|
|
14
|
+
return '<div class="screen-section" id="screen-' + code + '-' + screen.sectionCode + '" style="margin-bottom:2rem;">' +
|
|
15
15
|
'<h3 style="color:var(--text-bright);font-size:1rem;margin-bottom:1rem;">' +
|
|
16
16
|
'<span style="color:var(--accent);">▸</span> ' + escapeHtml(screen.sectionLabel || screen.sectionCode) +
|
|
17
17
|
'</h3>' +
|
|
@@ -110,11 +110,11 @@
|
|
|
110
110
|
.nav-icon-section { font-size: 0.5rem; color: var(--accent); }
|
|
111
111
|
.nav-icon-resource { font-size: 0.7rem; color: var(--border-light); }
|
|
112
112
|
.nav-resource-link {
|
|
113
|
-
cursor:
|
|
113
|
+
cursor: pointer;
|
|
114
114
|
font-size: 0.72rem;
|
|
115
115
|
color: var(--text-muted);
|
|
116
116
|
padding-top: 0.2rem;
|
|
117
117
|
padding-bottom: 0.2rem;
|
|
118
118
|
}
|
|
119
|
-
.nav-resource-link:hover { background:
|
|
119
|
+
.nav-resource-link:hover { background: var(--bg-hover); color: var(--accent); }
|
|
120
120
|
.nav-resources { margin-left: 0.5rem; }
|
|
@@ -443,6 +443,44 @@
|
|
|
443
443
|
color: var(--text-muted);
|
|
444
444
|
}
|
|
445
445
|
|
|
446
|
+
/* ============================================
|
|
447
|
+
STRUCTURE LEGEND
|
|
448
|
+
============================================ */
|
|
449
|
+
.struct-legend {
|
|
450
|
+
background: var(--bg-card);
|
|
451
|
+
border: 1px solid var(--border);
|
|
452
|
+
border-radius: 10px;
|
|
453
|
+
padding: 0.75rem 1rem;
|
|
454
|
+
margin-bottom: 1.25rem;
|
|
455
|
+
}
|
|
456
|
+
.struct-legend-title {
|
|
457
|
+
font-size: 0.8rem;
|
|
458
|
+
font-weight: 600;
|
|
459
|
+
color: var(--text-muted);
|
|
460
|
+
margin-bottom: 0.5rem;
|
|
461
|
+
}
|
|
462
|
+
.struct-legend-grid {
|
|
463
|
+
display: grid;
|
|
464
|
+
grid-template-columns: 1fr 1fr;
|
|
465
|
+
gap: 0.4rem 1.5rem;
|
|
466
|
+
}
|
|
467
|
+
.struct-legend-item {
|
|
468
|
+
font-size: 0.78rem;
|
|
469
|
+
color: var(--text-muted);
|
|
470
|
+
line-height: 1.4;
|
|
471
|
+
}
|
|
472
|
+
.struct-legend-code {
|
|
473
|
+
display: inline-block;
|
|
474
|
+
font-weight: 600;
|
|
475
|
+
color: var(--accent);
|
|
476
|
+
background: rgba(6,182,212,0.1);
|
|
477
|
+
padding: 0.05rem 0.4rem;
|
|
478
|
+
border-radius: 3px;
|
|
479
|
+
font-size: 0.72rem;
|
|
480
|
+
margin-right: 0.3rem;
|
|
481
|
+
font-family: monospace;
|
|
482
|
+
}
|
|
483
|
+
|
|
446
484
|
/* ============================================
|
|
447
485
|
SECTION GROUPS (Hierarchical Mode)
|
|
448
486
|
============================================ */
|