@atlashub/smartstack-cli 4.74.0 → 4.76.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +152 -31
- package/dist/index.js.map +1 -1
- package/dist/mcp-entry.mjs +14 -3
- package/dist/mcp-entry.mjs.map +1 -1
- package/package.json +1 -1
- package/templates/agents/ba-reader.md +17 -15
- package/templates/agents/ba-writer.md +49 -51
- package/templates/skills/apex/SKILL.md +2 -2
- package/templates/skills/apex/_shared.md +1 -1
- package/templates/skills/apex/references/checks/backend-checks.sh +21 -7
- package/templates/skills/apex/references/checks/frontend-checks.sh +26 -0
- package/templates/skills/apex/references/checks/infrastructure-checks.sh +47 -10
- package/templates/skills/apex/references/checks/seed-checks.sh +47 -7
- package/templates/skills/apex/references/core-seed-data.md +20 -18
- package/templates/skills/apex/references/frontend-route-wiring-app-tsx.md +3 -0
- package/templates/skills/apex/references/post-checks.md +23 -3
- package/templates/skills/apex/references/smartstack-api.md +4 -4
- package/templates/skills/apex/references/smartstack-frontend.md +54 -8
- package/templates/skills/apex/references/smartstack-layers.md +6 -6
- package/templates/skills/apex/steps/step-00-init.md +75 -1
- package/templates/skills/apex/steps/step-03-execute.md +16 -4
- package/templates/skills/apex/steps/step-03b-layer1-seed.md +65 -6
- package/templates/skills/apex/steps/step-03c-layer2-backend.md +50 -5
- package/templates/skills/apex/steps/step-03d-layer3-frontend.md +226 -4
- package/templates/skills/apex/steps/step-04-examine.md +163 -0
- package/templates/skills/apex-verify/SKILL.md +110 -0
- package/templates/skills/apex-verify/references/audit-rules.md +50 -0
- package/templates/skills/apex-verify/steps/step-00-init.md +119 -0
- package/templates/skills/apex-verify/steps/step-01-nav-audit.md +92 -0
- package/templates/skills/apex-verify/steps/step-02-crud-audit.md +127 -0
- package/templates/skills/apex-verify/steps/step-03-perm-audit.md +119 -0
- package/templates/skills/apex-verify/steps/step-04-route-audit.md +98 -0
- package/templates/skills/apex-verify/steps/step-05-report.md +110 -0
- package/templates/skills/application/references/frontend-route-wiring-app-tsx.md +3 -0
- package/templates/skills/application/templates-frontend.md +2 -2
- package/templates/skills/business-analyse/SKILL.md +17 -3
- package/templates/skills/business-analyse/_shared.md +64 -0
- package/templates/skills/business-analyse/patterns/suggestion-catalog.md +34 -26
- package/templates/skills/business-analyse/questionnaire/01-context.md +13 -9
- package/templates/skills/business-analyse/questionnaire/02-stakeholders-scope.md +20 -27
- package/templates/skills/business-analyse/questionnaire.md +86 -9
- package/templates/skills/business-analyse/references/03-json-schemas.md +221 -0
- package/templates/skills/business-analyse/references/03-post-check-validation.md +208 -0
- package/templates/skills/business-analyse/references/03-smartstack-entity-guards.md +32 -0
- package/templates/skills/business-analyse/references/04-cross-module-validation.md +95 -0
- package/templates/skills/business-analyse/references/04-file-allocation.md +162 -0
- package/templates/skills/business-analyse/references/04-naming-audit-checks.md +174 -0
- package/templates/skills/business-analyse/references/04-semantic-validation-matrix.md +118 -0
- package/templates/skills/business-analyse/references/canonical-json-formats.md +7 -3
- package/templates/skills/business-analyse/references/domain-research-playbook.md +234 -0
- package/templates/skills/business-analyse/references/entity-sourcing-presentation.md +166 -0
- package/templates/skills/business-analyse/references/init-resume-logic.md +70 -0
- package/templates/skills/business-analyse/references/module-completeness-challenge.md +174 -0
- package/templates/skills/business-analyse/references/multi-app-detection.md +149 -0
- package/templates/skills/business-analyse/references/portal-classification.md +52 -0
- package/templates/skills/business-analyse/references/robustness-checks.md +1 -1
- package/templates/skills/business-analyse/references/validation-checklist.md +35 -6
- package/templates/skills/business-analyse/schemas/sections/analysis-schema.json +50 -6
- package/templates/skills/business-analyse/steps/step-00-init.md +22 -190
- package/templates/skills/business-analyse/steps/step-01-cadrage.md +365 -269
- package/templates/skills/business-analyse/steps/step-02-structure.md +98 -20
- package/templates/skills/business-analyse/steps/step-03-specify.md +810 -229
- package/templates/skills/business-analyse/steps/step-04-consolidate.md +509 -278
- package/templates/skills/business-analyse-design/SKILL.md +10 -0
- package/templates/skills/business-analyse-design/references/screens-post-check.md +221 -0
- package/templates/skills/business-analyse-design/references/screens-type-mapping.md +138 -0
- package/templates/skills/business-analyse-design/references/smartcomponents-templates.md +225 -0
- package/templates/skills/{business-analyse → business-analyse-design}/references/spec-auto-inference.md +117 -117
- package/templates/skills/business-analyse-design/steps/step-01-screens.md +36 -162
- package/templates/skills/business-analyse-design/steps/step-02-wireframes.md +8 -7
- package/templates/skills/business-analyse-design/steps/step-03-navigation.md +89 -42
- package/templates/skills/business-analyse-develop/references/compact-loop.md +9 -0
- package/templates/skills/business-analyse-develop/references/handoff-quality-gate.md +132 -0
- package/templates/skills/business-analyse-develop/references/prd-v3-transformation.md +326 -0
- package/templates/skills/business-analyse-develop/references/report-reconciliation.md +140 -0
- package/templates/skills/business-analyse-develop/references/report-template.md +142 -0
- package/templates/skills/business-analyse-develop/steps/step-01-task.md +5 -177
- package/templates/skills/business-analyse-develop/steps/step-02-execute.md +17 -4
- package/templates/skills/business-analyse-develop/steps/step-03-commit.md +6 -2
- package/templates/skills/business-analyse-develop/steps/step-04-check.md +6 -0
- package/templates/skills/business-analyse-develop/steps/step-05-report.md +3 -269
- package/templates/skills/business-analyse-handoff/SKILL.md +10 -0
- package/templates/skills/business-analyse-handoff/references/agent-handoff-transform-prompt.md +211 -0
- package/templates/skills/business-analyse-handoff/references/context-isolation-pattern.md +47 -0
- package/templates/skills/business-analyse-handoff/references/handoff-file-inventory.md +49 -0
- package/templates/skills/business-analyse-handoff/references/handoff-global-validation.md +142 -0
- package/templates/skills/business-analyse-handoff/references/prd-validation-checks.md +125 -0
- package/templates/skills/business-analyse-handoff/references/project-index-update.md +98 -0
- package/templates/skills/business-analyse-handoff/steps/step-01-transform.md +9 -160
- package/templates/skills/business-analyse-handoff/steps/step-02-export.md +10 -99
- package/templates/skills/business-analyse-html/SKILL.md +10 -0
- package/templates/skills/business-analyse-html/html/ba-interactive.html +504 -97
- package/templates/skills/business-analyse-html/html/src/scripts/01-data-init.js +79 -2
- package/templates/skills/business-analyse-html/html/src/scripts/02-navigation.js +6 -46
- package/templates/skills/business-analyse-html/html/src/scripts/05-render-specs.js +80 -11
- package/templates/skills/business-analyse-html/html/src/scripts/06-render-consolidation.js +2 -2
- package/templates/skills/business-analyse-html/html/src/scripts/06-render-mockups.js +94 -36
- package/templates/skills/business-analyse-html/html/src/scripts/12-render-diagrams.js +162 -0
- package/templates/skills/business-analyse-html/html/src/styles/10-diagrams.css +73 -0
- package/templates/skills/business-analyse-html/html/src/template.html +2 -0
- package/templates/skills/business-analyse-html/references/02-embedded-artifacts-building.md +144 -0
- package/templates/skills/business-analyse-html/references/02-feature-data-building.md +143 -0
- package/templates/skills/business-analyse-html/references/02-mapping-tables.md +442 -0
- package/templates/skills/business-analyse-html/references/02-normalization-helpers.md +139 -0
- package/templates/skills/business-analyse-html/references/02-screen-format-detection.md +283 -0
- package/templates/skills/business-analyse-html/references/02-self-check-validation.md +199 -0
- package/templates/skills/business-analyse-html/references/data-build.md +24 -1
- package/templates/skills/business-analyse-html/references/data-mapping.md +119 -17
- package/templates/skills/business-analyse-html/steps/step-02-build-data.md +18 -555
- package/templates/skills/business-analyse-html/steps/step-04-verify.md +92 -3
- package/templates/skills/business-analyse-quick/SKILL.md +807 -0
- package/templates/skills/{sketch → business-analyse-quick}/references/domain-heuristics.md +59 -3
- package/templates/skills/business-analyse-quick/references/prd-schema.md +268 -0
- package/templates/skills/business-analyse-review/SKILL.md +10 -0
- package/templates/skills/business-analyse-review/references/review-data-mapping.md +6 -0
- package/templates/skills/business-analyse-status/SKILL.md +8 -0
- package/templates/skills/dev-start/SKILL.md +143 -307
- package/templates/skills/efcore/SKILL.md +13 -0
- package/templates/skills/sketch/SKILL.md +15 -153
- package/templates/skills/ui-components/SKILL.md +1 -1
- package/templates/skills/ui-components/patterns/data-table.md +1 -1
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: 02-screen-format-detection
|
|
3
|
+
description: Detection and normalization logic for screens.json format variants (A, B-CANONICAL, B-LEGACY)
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Screen Format Detection
|
|
7
|
+
|
|
8
|
+
The `screens.json` file can be produced in multiple formats depending on the BA workflow step that generated it. This reference documents the detection logic and normalization for each format variant.
|
|
9
|
+
|
|
10
|
+
## Format Overview
|
|
11
|
+
|
|
12
|
+
| Format | Structure | Source | Key Fields |
|
|
13
|
+
|--------|-----------|--------|-----------|
|
|
14
|
+
| **A** | `screens[]` (flat) | ba-003 (original BA output) | `screen`, `section`, `columns[]`, `filters[]`, `tabs[]`, `actions[]`, `kpis[]`, `charts[]` |
|
|
15
|
+
| **B-CANONICAL** | `sections[].resources[]` | ba-005+ (design output) | `sectionCode`, `sectionLabel`, `resources[]` with nested structure |
|
|
16
|
+
| **B-LEGACY** | `sections[]` (flat within section) | ba-004 (intermediate step) | `sections[]` with data directly on section, no resources[] nesting |
|
|
17
|
+
|
|
18
|
+
## Format A: Flat screens[] Array
|
|
19
|
+
|
|
20
|
+
**Detection:** `mod.screens?.screens` array exists and has length > 0.
|
|
21
|
+
|
|
22
|
+
**Schema:**
|
|
23
|
+
```javascript
|
|
24
|
+
screens: [
|
|
25
|
+
{
|
|
26
|
+
screen: "ScreenName",
|
|
27
|
+
section: "SectionCode",
|
|
28
|
+
sectionLabel: "Section Label",
|
|
29
|
+
description: "...",
|
|
30
|
+
sectionDescription: "...",
|
|
31
|
+
componentType: "SmartTable|SmartForm|Dashboard|Kanban",
|
|
32
|
+
columns: [...], // for table components
|
|
33
|
+
filters: [...], // simple filters
|
|
34
|
+
tabs: [...], // form tabs
|
|
35
|
+
actions: [...], // action buttons
|
|
36
|
+
kpis: [...], // dashboard KPIs
|
|
37
|
+
charts: [...], // dashboard charts
|
|
38
|
+
options: [...], // component options
|
|
39
|
+
permission: "...", // ACL permission
|
|
40
|
+
mockup: "...", // wireframe content
|
|
41
|
+
mockupFormat: "..." // wireframe format
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Normalization:**
|
|
47
|
+
|
|
48
|
+
Group flat screens by section, then map each to a `{sectionCode, sectionLabel, resources[]}` structure:
|
|
49
|
+
|
|
50
|
+
```javascript
|
|
51
|
+
if (flatScr.length > 0) {
|
|
52
|
+
// FORMAT A: flat screens[] array (ba-003 style)
|
|
53
|
+
const bySec = {};
|
|
54
|
+
flatScr.forEach(s => {
|
|
55
|
+
const sec = s.section || "default";
|
|
56
|
+
if (!bySec[sec]) bySec[sec] = {
|
|
57
|
+
sectionCode: sec,
|
|
58
|
+
sectionLabel: s.sectionLabel || s.sectionDescription || sec,
|
|
59
|
+
resources: []
|
|
60
|
+
};
|
|
61
|
+
bySec[sec].resources.push({
|
|
62
|
+
code: s.screen || s.name || "",
|
|
63
|
+
label: s.sectionLabel || s.description || s.screen || "",
|
|
64
|
+
type: s.componentType || "unknown",
|
|
65
|
+
columns: (s.columns || []).map(normalizeColumn),
|
|
66
|
+
filters: (s.filters || []).map(normalizeFilter),
|
|
67
|
+
fields: [],
|
|
68
|
+
tabs: (s.tabs || []).map(t => ({
|
|
69
|
+
label: t.label || t.tabLabel || t.code || "",
|
|
70
|
+
fields: (t.fields || []).map(normalizeField)
|
|
71
|
+
})),
|
|
72
|
+
actions: (s.actions || []).map(normalizeAction),
|
|
73
|
+
kpis: (s.kpis || []).map(normalizeKpi),
|
|
74
|
+
charts: (s.charts || []).map(normalizeChart),
|
|
75
|
+
options: s.options || [],
|
|
76
|
+
permission: s.permission || "",
|
|
77
|
+
notes: s.description || s.sectionDescription || ""
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
screens = Object.values(bySec);
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Output:** Array of `{sectionCode, sectionLabel, resources[]}` objects (equivalent to B-CANONICAL).
|
|
85
|
+
|
|
86
|
+
## Format B: Detect Sub-variant (B-CANONICAL vs B-LEGACY)
|
|
87
|
+
|
|
88
|
+
**Detection:** `mod.screens?.sections` array exists and has length > 0.
|
|
89
|
+
|
|
90
|
+
**Decision point:** Check if any section contains `resources[]`:
|
|
91
|
+
|
|
92
|
+
```javascript
|
|
93
|
+
const hasNestedResources = sectionScr.some(sec => (sec.resources || []).length > 0);
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Format B-CANONICAL: sections[] with resources[]
|
|
97
|
+
|
|
98
|
+
**Schema:**
|
|
99
|
+
```javascript
|
|
100
|
+
sections: [
|
|
101
|
+
{
|
|
102
|
+
sectionCode: "SectionCode",
|
|
103
|
+
sectionLabel: "Section Label",
|
|
104
|
+
displayName: "...",
|
|
105
|
+
label: "...",
|
|
106
|
+
id: "...",
|
|
107
|
+
code: "...",
|
|
108
|
+
resources: [
|
|
109
|
+
{
|
|
110
|
+
code: "ResourceCode",
|
|
111
|
+
id: "...",
|
|
112
|
+
label: "Resource Label",
|
|
113
|
+
displayName: "...",
|
|
114
|
+
type: "SmartTable|SmartForm|Dashboard|Kanban",
|
|
115
|
+
componentType: "...",
|
|
116
|
+
layout: "...",
|
|
117
|
+
columns: [...], // normalized column definitions
|
|
118
|
+
filters: [...], // SmartFilter-style filters
|
|
119
|
+
tabs: [...], // form tabs
|
|
120
|
+
actions: [...], // action buttons
|
|
121
|
+
kpis: [...], // KPIs
|
|
122
|
+
charts: [...], // chart definitions
|
|
123
|
+
options: [...], // component options
|
|
124
|
+
permission: "...", // ACL permission
|
|
125
|
+
notes: "...", // description
|
|
126
|
+
description: "..."
|
|
127
|
+
}
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
]
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Normalization:**
|
|
134
|
+
|
|
135
|
+
```javascript
|
|
136
|
+
if (hasNestedResources) {
|
|
137
|
+
// FORMAT B-CANONICAL: sections[] with resources[] (ba-005+ style)
|
|
138
|
+
screens = sectionScr.map(sec => ({
|
|
139
|
+
sectionCode: sec.sectionCode || sec.id || sec.code || "",
|
|
140
|
+
sectionLabel: sec.sectionLabel || sec.displayName || sec.label || sec.sectionCode || "",
|
|
141
|
+
resources: (sec.resources || []).map(res => ({
|
|
142
|
+
code: res.code || res.id || "",
|
|
143
|
+
label: res.label || res.displayName || res.code || "",
|
|
144
|
+
type: res.type || res.componentType || res.layout || "unknown",
|
|
145
|
+
columns: (res.columns || []).map(normalizeColumn),
|
|
146
|
+
filters: res.type === 'SmartFilter'
|
|
147
|
+
? (res.filters || []).map(normalizeSmartFilterField)
|
|
148
|
+
: (res.filters || []).map(normalizeFilter),
|
|
149
|
+
fields: [],
|
|
150
|
+
tabs: (res.tabs || []).map(t => ({
|
|
151
|
+
label: t.label || t.displayName || t.code || t.id || "",
|
|
152
|
+
fields: (t.fields || []).map(normalizeField)
|
|
153
|
+
})),
|
|
154
|
+
actions: (res.actions || []).map(normalizeAction),
|
|
155
|
+
kpis: (res.kpis || []).map(normalizeKpi),
|
|
156
|
+
charts: (res.charts || []).map(normalizeChart),
|
|
157
|
+
options: res.options || [],
|
|
158
|
+
permission: res.permission || "",
|
|
159
|
+
notes: res.notes || res.description || ""
|
|
160
|
+
}))
|
|
161
|
+
}));
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**Key feature:** SmartFilter type detected and uses rich filter normalization (`normalizeSmartFilterField`) instead of simple label extraction.
|
|
166
|
+
|
|
167
|
+
### Format B-LEGACY: sections[] without resources[]
|
|
168
|
+
|
|
169
|
+
**Schema:**
|
|
170
|
+
```javascript
|
|
171
|
+
sections: [
|
|
172
|
+
{
|
|
173
|
+
id: "SectionId",
|
|
174
|
+
code: "SectionCode",
|
|
175
|
+
sectionCode: "...",
|
|
176
|
+
displayName: "Section Label",
|
|
177
|
+
label: "...",
|
|
178
|
+
layout: "SmartTable|SmartForm|Dashboard",
|
|
179
|
+
componentType: "...",
|
|
180
|
+
columns: [...], // data directly on section
|
|
181
|
+
filters: [...], // simple filters
|
|
182
|
+
tabs: [...], // form tabs
|
|
183
|
+
actions: [...], // action buttons
|
|
184
|
+
kpis: [...], // KPIs
|
|
185
|
+
charts: [...], // chart definitions
|
|
186
|
+
options: [...], // options
|
|
187
|
+
permissions: {view: "..."} or permission: "...",
|
|
188
|
+
description: "...",
|
|
189
|
+
// NO resources[] nesting
|
|
190
|
+
}
|
|
191
|
+
]
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**Normalization:**
|
|
195
|
+
|
|
196
|
+
Group sections by ID/code, then map into `{sectionCode, sectionLabel, resources[]}` structure:
|
|
197
|
+
|
|
198
|
+
```javascript
|
|
199
|
+
} else {
|
|
200
|
+
// FORMAT B-LEGACY: sections[] without resources[] (ba-004 style)
|
|
201
|
+
const bySec = {};
|
|
202
|
+
sectionScr.forEach(sec => {
|
|
203
|
+
const secId = sec.id || sec.code || sec.sectionCode || "";
|
|
204
|
+
const secLabel = sec.displayName || sec.label || sec.sectionLabel || secId;
|
|
205
|
+
const componentType = sec.layout || sec.componentType || "unknown";
|
|
206
|
+
if (!bySec[secId]) bySec[secId] = {
|
|
207
|
+
sectionCode: secId,
|
|
208
|
+
sectionLabel: secLabel,
|
|
209
|
+
resources: []
|
|
210
|
+
};
|
|
211
|
+
bySec[secId].resources.push({
|
|
212
|
+
code: secId,
|
|
213
|
+
label: secLabel,
|
|
214
|
+
type: componentType,
|
|
215
|
+
columns: (sec.columns || []).map(normalizeColumn),
|
|
216
|
+
filters: (sec.filters || []).map(normalizeFilter),
|
|
217
|
+
fields: [],
|
|
218
|
+
tabs: (sec.tabs || []).map(t => ({
|
|
219
|
+
label: t.displayName || t.label || t.code || t.id || "",
|
|
220
|
+
fields: (t.fields || []).map(normalizeField)
|
|
221
|
+
})),
|
|
222
|
+
actions: (sec.actions || []).map(normalizeAction),
|
|
223
|
+
kpis: (sec.kpis || []).map(normalizeKpi),
|
|
224
|
+
charts: (sec.charts || []).map(normalizeChart),
|
|
225
|
+
options: sec.options || [],
|
|
226
|
+
permission: (typeof sec.permissions === 'object' ? sec.permissions?.view : sec.permission) || "",
|
|
227
|
+
notes: sec.description || ""
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
screens = Object.values(bySec);
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**Key differences:**
|
|
235
|
+
- Sections have data directly (no `resources[]` nesting)
|
|
236
|
+
- Permissions may be object `{view: "..."}` or simple string
|
|
237
|
+
- One resource per section (grouped by ID)
|
|
238
|
+
|
|
239
|
+
## Output Normalization
|
|
240
|
+
|
|
241
|
+
All three formats normalize to a **canonical output structure**:
|
|
242
|
+
|
|
243
|
+
```javascript
|
|
244
|
+
screens: [
|
|
245
|
+
{
|
|
246
|
+
sectionCode: "string",
|
|
247
|
+
sectionLabel: "string",
|
|
248
|
+
resources: [
|
|
249
|
+
{
|
|
250
|
+
code: "string",
|
|
251
|
+
label: "string",
|
|
252
|
+
type: "string",
|
|
253
|
+
columns: [...], // normalized via normalizeColumn()
|
|
254
|
+
filters: [...], // normalized via normalizeFilter() or normalizeSmartFilterField()
|
|
255
|
+
fields: [],
|
|
256
|
+
tabs: [...], // with normalized fields
|
|
257
|
+
actions: [...], // normalized via normalizeAction()
|
|
258
|
+
kpis: [...], // normalized via normalizeKpi()
|
|
259
|
+
charts: [...], // normalized via normalizeChart()
|
|
260
|
+
options: [...],
|
|
261
|
+
permission: "string",
|
|
262
|
+
notes: "string"
|
|
263
|
+
}
|
|
264
|
+
]
|
|
265
|
+
}
|
|
266
|
+
]
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
This canonical form is then used to populate `moduleSpecs[moduleCode].screens` and render in the HTML viewer.
|
|
270
|
+
|
|
271
|
+
## Detection Flow
|
|
272
|
+
|
|
273
|
+
```
|
|
274
|
+
mod.screens exists?
|
|
275
|
+
├─ YES: Do we have mod.screens.screens[] with length > 0?
|
|
276
|
+
│ └─ YES: Format A (flat) → normalize by section → canonical
|
|
277
|
+
│ └─ NO: Continue to B detection
|
|
278
|
+
├─ Do we have mod.screens.sections[] with length > 0?
|
|
279
|
+
│ └─ YES: Check hasNestedResources (any section.resources[] exists?)
|
|
280
|
+
│ ├─ YES: Format B-CANONICAL → normalize permissions → canonical
|
|
281
|
+
│ └─ NO: Format B-LEGACY → group by ID → canonical
|
|
282
|
+
└─ NO: screens = [] (empty)
|
|
283
|
+
```
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: 02-self-check-validation
|
|
3
|
+
description: Post-build self-check validation to detect data loss when building FEATURE_DATA
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Self-Check Validation
|
|
7
|
+
|
|
8
|
+
After building `FEATURE_DATA.moduleSpecs` and enriching `anticipatedSections` with section-level use cases and business rules, run this mandatory self-check to detect data loss between the source files and the built object.
|
|
9
|
+
|
|
10
|
+
## Purpose
|
|
11
|
+
|
|
12
|
+
Ensures that no useCases, businessRules, entities, or screens were lost during the normalization and mapping process. Data loss indicates a bug in the build logic (e.g., missing array handling, failed normalization, wrong field names).
|
|
13
|
+
|
|
14
|
+
## Execution Timing
|
|
15
|
+
|
|
16
|
+
**AFTER:**
|
|
17
|
+
1. All `moduleSpecs[moduleCode]` entries are populated
|
|
18
|
+
2. `anticipatedSections` are enriched with section-level UC/BR
|
|
19
|
+
|
|
20
|
+
**BEFORE:**
|
|
21
|
+
- Proceeding to step-03 (HTML rendering)
|
|
22
|
+
|
|
23
|
+
## Self-Check Code
|
|
24
|
+
|
|
25
|
+
```javascript
|
|
26
|
+
// SELF-CHECK: compare source file counts vs FEATURE_DATA counts
|
|
27
|
+
const errors = [];
|
|
28
|
+
FEATURE_DATA.modules.forEach(m => {
|
|
29
|
+
const spec = FEATURE_DATA.moduleSpecs[m.code];
|
|
30
|
+
const source = collected_data.modules[m.code];
|
|
31
|
+
if (!spec) { errors.push(`MISSING moduleSpecs[${m.code}]`); return; }
|
|
32
|
+
|
|
33
|
+
// Check useCases (handle both key conventions)
|
|
34
|
+
const srcUC = (source?.usecases?.useCases || source?.usecases?.usecases || []).length;
|
|
35
|
+
const bltUC = (spec.useCases || []).length;
|
|
36
|
+
if (srcUC > 0 && bltUC === 0)
|
|
37
|
+
errors.push(`${m.code}: useCases EMPTY but source has ${srcUC}`);
|
|
38
|
+
|
|
39
|
+
// Check businessRules (handle both key conventions)
|
|
40
|
+
const srcBR = (source?.rules?.rules || source?.rules?.businessRules || []).length;
|
|
41
|
+
const bltBR = (spec.businessRules || []).length;
|
|
42
|
+
if (srcBR > 0 && bltBR === 0)
|
|
43
|
+
errors.push(`${m.code}: businessRules EMPTY but source has ${srcBR}`);
|
|
44
|
+
|
|
45
|
+
// Check entities
|
|
46
|
+
const srcEnt = (source?.entities?.entities || []).length;
|
|
47
|
+
const bltEnt = (spec.entities || []).length;
|
|
48
|
+
if (srcEnt > 0 && bltEnt === 0)
|
|
49
|
+
errors.push(`${m.code}: entities EMPTY but source has ${srcEnt}`);
|
|
50
|
+
|
|
51
|
+
// Check screens (handle both formats: screens[] and sections[])
|
|
52
|
+
const srcScreens = (source?.screens?.screens || source?.screens?.sections || []).length;
|
|
53
|
+
const bltScreenResources = (spec.screens || []).reduce(
|
|
54
|
+
(acc, s) => acc + (s.resources || []).length, 0);
|
|
55
|
+
if (srcScreens > 0 && bltScreenResources === 0)
|
|
56
|
+
errors.push(`${m.code}: screens EMPTY (0 resources) but source has ${srcScreens} screens/sections`);
|
|
57
|
+
|
|
58
|
+
// Check serialization: [object Object] in useCases steps = BUG
|
|
59
|
+
(spec.useCases || []).forEach(uc => {
|
|
60
|
+
if (uc.steps && uc.steps.includes("[object Object]"))
|
|
61
|
+
errors.push(`${m.code}: UC "${uc.name}" has [object Object] in steps — steps[] contains objects not strings`);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
if (errors.length > 0) {
|
|
66
|
+
Display("⛔ SELF-CHECK FAILED — data loss detected:");
|
|
67
|
+
errors.forEach(e => Display(" - " + e));
|
|
68
|
+
// FIX: re-map the failing modules from collected_data before continuing
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Validation Points
|
|
73
|
+
|
|
74
|
+
### 1. moduleSpecs Structure
|
|
75
|
+
|
|
76
|
+
**Check:** Every module in `FEATURE_DATA.modules` has a corresponding entry in `FEATURE_DATA.moduleSpecs[moduleCode]`.
|
|
77
|
+
|
|
78
|
+
**Failure Symptom:** `MISSING moduleSpecs[${m.code}]`
|
|
79
|
+
|
|
80
|
+
**Fix:** Ensure the build loop populates `moduleSpecs[moduleCode]` for ALL modules.
|
|
81
|
+
|
|
82
|
+
### 2. useCases Count
|
|
83
|
+
|
|
84
|
+
**Check:** If source file has useCases (`usecases.useCases` or `usecases.usecases`), the built `spec.useCases` array must not be empty.
|
|
85
|
+
|
|
86
|
+
**Failure Symptom:** `${m.code}: useCases EMPTY but source has ${srcUC}`
|
|
87
|
+
|
|
88
|
+
**Common Causes:**
|
|
89
|
+
- Field is `usecases` but code looks for `useCases` (camelCase mismatch)
|
|
90
|
+
- Nested field is `usecases` instead of `useCases` (lowercase variant)
|
|
91
|
+
- Mapping function didn't handle array correctly
|
|
92
|
+
|
|
93
|
+
**Fix:** Check field names in `mod.usecases?.useCases || mod.usecases?.usecases`.
|
|
94
|
+
|
|
95
|
+
### 3. businessRules Count
|
|
96
|
+
|
|
97
|
+
**Check:** If source file has businessRules (`rules.rules` or `rules.businessRules`), the built `spec.businessRules` array must not be empty.
|
|
98
|
+
|
|
99
|
+
**Failure Symptom:** `${m.code}: businessRules EMPTY but source has ${srcBR}`
|
|
100
|
+
|
|
101
|
+
**Common Causes:**
|
|
102
|
+
- Field is `businessRules` but code looks for `rules` (nested field name mismatch)
|
|
103
|
+
- Rules array is not being mapped correctly
|
|
104
|
+
|
|
105
|
+
**Fix:** Check field names in `mod.rules?.rules || mod.rules?.businessRules`.
|
|
106
|
+
|
|
107
|
+
### 4. Entities Count
|
|
108
|
+
|
|
109
|
+
**Check:** If source file has entities (`entities.entities`), the built `spec.entities` array must not be empty.
|
|
110
|
+
|
|
111
|
+
**Failure Symptom:** `${m.code}: entities EMPTY but source has ${srcEnt}`
|
|
112
|
+
|
|
113
|
+
**Common Causes:**
|
|
114
|
+
- Mapping didn't iterate over entities array
|
|
115
|
+
- Fallback to `fields[]` when `attributes[]` is missing not working
|
|
116
|
+
|
|
117
|
+
**Fix:** Check the entities mapping includes both `attributes[]` and `fields[]` fallback.
|
|
118
|
+
|
|
119
|
+
### 5. Screens Count
|
|
120
|
+
|
|
121
|
+
**Check:** If source file has screens (either `screens.screens[]` or `screens.sections[]`), the normalized `spec.screens[].resources[]` must have at least the same number of total resources.
|
|
122
|
+
|
|
123
|
+
**Failure Symptom:** `${m.code}: screens EMPTY (0 resources) but source has ${srcScreens} screens/sections`
|
|
124
|
+
|
|
125
|
+
**Common Causes:**
|
|
126
|
+
- Format detection logic failed (neither Format A nor B found)
|
|
127
|
+
- Screen format detection chose the wrong branch
|
|
128
|
+
- `normalizeColumn`, `normalizeField`, `normalizeFilter` functions not applied
|
|
129
|
+
|
|
130
|
+
**Fix:**
|
|
131
|
+
1. Verify `mod.screens.screens` or `mod.screens.sections` exists
|
|
132
|
+
2. Run format detection logic step-by-step
|
|
133
|
+
3. Ensure screen resources are being pushed into the array
|
|
134
|
+
|
|
135
|
+
### 6. Serialization Bug: [object Object]
|
|
136
|
+
|
|
137
|
+
**Check:** useCases steps field must be a string (or converted to string via `.join()`). If it contains `[object Object]`, the steps array contains unconverted objects.
|
|
138
|
+
|
|
139
|
+
**Failure Symptom:** `${m.code}: UC "${uc.name}" has [object Object] in steps — steps[] contains objects not strings`
|
|
140
|
+
|
|
141
|
+
**Fix:** Ensure the mapping converts step objects to strings:
|
|
142
|
+
```javascript
|
|
143
|
+
steps: (uc.mainScenario || uc.steps || []).map(s =>
|
|
144
|
+
typeof s === 'string' ? s : (s.action || s.description || "")
|
|
145
|
+
).join("\n") // .join() is CRITICAL to convert array to string
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Resolution Workflow
|
|
149
|
+
|
|
150
|
+
When self-check fails:
|
|
151
|
+
|
|
152
|
+
1. **Identify failing module** from error message
|
|
153
|
+
2. **Locate the source file** in `collected_data.modules[m.code]`
|
|
154
|
+
3. **Compare field structure** between source and mapping code
|
|
155
|
+
4. **Fix the mapping** (update field names, add fallbacks, fix type conversions)
|
|
156
|
+
5. **Re-build moduleSpecs** for the failing module
|
|
157
|
+
6. **Re-run self-check** to verify fix
|
|
158
|
+
|
|
159
|
+
## Post-Check Actions
|
|
160
|
+
|
|
161
|
+
If self-check **PASSES**:
|
|
162
|
+
- Continue to step-03 (HTML rendering)
|
|
163
|
+
- No further data validation needed
|
|
164
|
+
|
|
165
|
+
If self-check **FAILS** with errors:
|
|
166
|
+
- DO NOT proceed to rendering
|
|
167
|
+
- Fix each error in the module build logic
|
|
168
|
+
- Re-build affected moduleSpecs entries
|
|
169
|
+
- Re-run self-check
|
|
170
|
+
|
|
171
|
+
## Expected Output
|
|
172
|
+
|
|
173
|
+
### Success Case
|
|
174
|
+
|
|
175
|
+
No errors array or empty:
|
|
176
|
+
```
|
|
177
|
+
✅ Self-check PASSED — all modules have complete data
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Failure Case
|
|
181
|
+
|
|
182
|
+
Display all errors:
|
|
183
|
+
```
|
|
184
|
+
⛔ SELF-CHECK FAILED — data loss detected:
|
|
185
|
+
- Employees: useCases EMPTY but source has 5
|
|
186
|
+
- Employees: UC "Create Employee" has [object Object] in steps — steps[] contains objects not strings
|
|
187
|
+
- Payroll: screens EMPTY (0 resources) but source has 3 screens/sections
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Design Rationale
|
|
193
|
+
|
|
194
|
+
The self-check is **mandatory and blocking** because:
|
|
195
|
+
|
|
196
|
+
1. **Silent data loss is worse than errors** — empty arrays are valid JavaScript but indicate a bug
|
|
197
|
+
2. **Hard to debug later** — if screens/UC/BR are missing, the HTML viewer will appear empty but rendering code will work
|
|
198
|
+
3. **Source of truth is always the collected files** — self-check compares against collected_data, not against user expectations
|
|
199
|
+
4. **Early detection** — catch bugs in step-02 before they cascade into step-03 rendering
|
|
@@ -94,7 +94,8 @@ const FEATURE_DATA = {
|
|
|
94
94
|
consolidation: {
|
|
95
95
|
integrations: master.consolidation.crossModuleInteractions || [],
|
|
96
96
|
sharedEntities: master.consolidation.sharedEntities || [],
|
|
97
|
-
sequenceDiagrams: master.consolidation.e2eFlows || []
|
|
97
|
+
sequenceDiagrams: master.consolidation.e2eFlows || [],
|
|
98
|
+
mermaidDiagrams: master.consolidation.mermaidDiagrams || {}
|
|
98
99
|
},
|
|
99
100
|
handoff: {
|
|
100
101
|
complexity: master.handoff.complexity,
|
|
@@ -122,6 +123,28 @@ const FEATURE_DATA = {
|
|
|
122
123
|
6. Extract consolidation data (integrations, shared entities, E2E flows)
|
|
123
124
|
7. Extract handoff section (complexity, strategy, module order, file counts)
|
|
124
125
|
|
|
126
|
+
### consolidation.mermaidDiagrams (Mermaid diagrams)
|
|
127
|
+
|
|
128
|
+
Source: `consolidation.json`.mermaidDiagrams
|
|
129
|
+
|
|
130
|
+
Generated by step-04-consolidate section 5b. Contains pre-built Mermaid diagram definitions
|
|
131
|
+
for rendering in the HTML viewer.
|
|
132
|
+
|
|
133
|
+
```javascript
|
|
134
|
+
mermaidDiagrams: {
|
|
135
|
+
erd: consolidation.mermaidDiagrams?.erd || null, // ERD string or null
|
|
136
|
+
mcd: consolidation.mermaidDiagrams?.mcd || null, // MCD string or null
|
|
137
|
+
useCases: consolidation.mermaidDiagrams?.useCases || {}, // {moduleCode: mermaid_def}
|
|
138
|
+
stateMachines: consolidation.mermaidDiagrams?.stateMachines || {}, // {entity: mermaid_def}
|
|
139
|
+
sequences: consolidation.mermaidDiagrams?.sequences || {} // {flowName: mermaid_def}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Rendered by `12-render-diagrams.js`:
|
|
144
|
+
- `erd` → inserted in `#dataModelContainer` (consol-datamodel section)
|
|
145
|
+
- `stateMachines` → appended to `#dataModelContainer` per entity
|
|
146
|
+
- `sequences` → appended to consol-flows section
|
|
147
|
+
|
|
125
148
|
## EMBEDDED_ARTIFACTS Object
|
|
126
149
|
|
|
127
150
|
> **CRITICAL:** The wireframes object is keyed by moduleCode (NOT a flat array).
|