@atlashub/smartstack-cli 4.74.0 → 4.75.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +111 -36
- 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/_shared.md +1 -1
- package/templates/skills/apex/references/checks/backend-checks.sh +21 -7
- package/templates/skills/apex/references/checks/infrastructure-checks.sh +47 -10
- package/templates/skills/apex/references/frontend-route-wiring-app-tsx.md +3 -0
- package/templates/skills/apex/references/post-checks.md +5 -2
- package/templates/skills/apex/references/smartstack-frontend.md +53 -7
- package/templates/skills/apex/steps/step-00-init.md +74 -0
- package/templates/skills/apex/steps/step-03-execute.md +16 -4
- package/templates/skills/apex/steps/step-03b-layer1-seed.md +39 -6
- package/templates/skills/apex/steps/step-03c-layer2-backend.md +50 -5
- package/templates/skills/apex/steps/step-03d-layer3-frontend.md +102 -2
- package/templates/skills/application/references/frontend-route-wiring-app-tsx.md +3 -0
- package/templates/skills/business-analyse/SKILL.md +14 -0
- package/templates/skills/business-analyse/_shared.md +27 -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 +213 -0
- package/templates/skills/business-analyse/references/03-post-check-validation.md +144 -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/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/validation-checklist.md +30 -1
- package/templates/skills/business-analyse/schemas/sections/analysis-schema.json +37 -4
- 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 +652 -229
- package/templates/skills/business-analyse/steps/step-04-consolidate.md +308 -287
- 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 +208 -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 +306 -81
- package/templates/skills/business-analyse-html/html/src/scripts/01-data-init.js +15 -2
- package/templates/skills/business-analyse-html/html/src/scripts/02-navigation.js +6 -46
- package/templates/skills/business-analyse-html/html/src/scripts/06-render-mockups.js +88 -33
- package/templates/skills/business-analyse-html/html/src/scripts/12-render-diagrams.js +116 -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 +141 -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 +22 -1
- package/templates/skills/business-analyse-html/references/data-mapping.md +40 -5
- package/templates/skills/business-analyse-html/steps/step-02-build-data.md +12 -555
- package/templates/skills/business-analyse-review/SKILL.md +10 -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
|
@@ -89,3 +89,13 @@ Client reviews HTML
|
|
|
89
89
|
## Entry Point
|
|
90
90
|
|
|
91
91
|
**FIRST ACTION:** Load `steps/step-01-screens.md`
|
|
92
|
+
|
|
93
|
+
<success_criteria>
|
|
94
|
+
- screens.json genere par module avec specifications section/resource
|
|
95
|
+
- Toutes les colonnes SmartTable referencent des attributs d'entite valides
|
|
96
|
+
- Tous les champs SmartForm referencent des attributs d'entite valides
|
|
97
|
+
- Tous les ecrans ont un champ permission valide depuis permissions.json
|
|
98
|
+
- navigation.json genere avec arbre de navigation complet
|
|
99
|
+
- Wireframes inclus dans screens.json avec mockupFormat et elements[]
|
|
100
|
+
- Aucune entite ou permission inventee (toutes referencent Phase 1)
|
|
101
|
+
</success_criteria>
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# Screens POST-CHECK Validation
|
|
2
|
+
|
|
3
|
+
This document contains the complete executable validation code for screens.json files. Run this validation after writing ALL screens.json files for a module.
|
|
4
|
+
|
|
5
|
+
## Validation Levels
|
|
6
|
+
|
|
7
|
+
- **BLOCKING errors:** Must be fixed before proceeding to the next step
|
|
8
|
+
- **WARNING errors:** Should be reviewed but do not block progress
|
|
9
|
+
|
|
10
|
+
## Validation Script
|
|
11
|
+
|
|
12
|
+
```javascript
|
|
13
|
+
for (const mod of modules) {
|
|
14
|
+
const screensPath = resolveModuleDir(mod.applicationCode, mod.code) + '/screens.json';
|
|
15
|
+
const entitiesPath = resolveModuleDir(mod.applicationCode, mod.code) + '/entities.json';
|
|
16
|
+
const permsPath = resolveModuleDir(mod.applicationCode, mod.code) + '/permissions.json';
|
|
17
|
+
|
|
18
|
+
const screens = READ(screensPath);
|
|
19
|
+
const entities = READ(entitiesPath);
|
|
20
|
+
const perms = READ(permsPath);
|
|
21
|
+
|
|
22
|
+
const entityNames = entities.entities.map(e => e.name);
|
|
23
|
+
const attrMap = {};
|
|
24
|
+
entities.entities.forEach(e => {
|
|
25
|
+
attrMap[e.name] = e.attributes.map(a => a.name);
|
|
26
|
+
});
|
|
27
|
+
const computedAttrs = {};
|
|
28
|
+
entities.entities.forEach(e => {
|
|
29
|
+
computedAttrs[e.name] = e.attributes.filter(a => a.computed).map(a => a.name);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
for (const section of screens.sections) {
|
|
33
|
+
// CHECK 1: Every section has at least 1 resource
|
|
34
|
+
ASSERT(section.resources.length > 0,
|
|
35
|
+
`BLOCKING: ${mod.code}.${section.sectionCode} has 0 resources`);
|
|
36
|
+
|
|
37
|
+
for (const res of section.resources) {
|
|
38
|
+
// CHECK 2: Every resource has a valid entity
|
|
39
|
+
ASSERT(entityNames.includes(res.entity),
|
|
40
|
+
`BLOCKING: ${res.code} references unknown entity "${res.entity}"`);
|
|
41
|
+
|
|
42
|
+
// CHECK 3: Every resource has a permission
|
|
43
|
+
ASSERT(res.permission,
|
|
44
|
+
`BLOCKING: ${res.code} missing permission`);
|
|
45
|
+
|
|
46
|
+
// CHECK 4: SmartTable columns reference valid attributes
|
|
47
|
+
if (res.type === 'SmartTable' && res.columns) {
|
|
48
|
+
for (const col of res.columns) {
|
|
49
|
+
const field = col.field.split('.')[0];
|
|
50
|
+
ASSERT(attrMap[res.entity]?.includes(field),
|
|
51
|
+
`BLOCKING: ${res.code} column "${col.field}" not in ${res.entity}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// CHECK 5: SmartForm fields reference valid attributes
|
|
56
|
+
if (res.type === 'SmartForm' && res.tabs) {
|
|
57
|
+
for (const tab of res.tabs) {
|
|
58
|
+
if (tab.fields) {
|
|
59
|
+
for (const f of tab.fields) {
|
|
60
|
+
ASSERT(attrMap[res.entity]?.includes(f.field),
|
|
61
|
+
`BLOCKING: ${res.code} field "${f.field}" not in ${res.entity}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// CHECK 6: Lookup fields have entity
|
|
68
|
+
if (res.type === 'SmartForm' && res.tabs) {
|
|
69
|
+
for (const tab of res.tabs) {
|
|
70
|
+
if (tab.fields) {
|
|
71
|
+
for (const f of tab.fields) {
|
|
72
|
+
if (f.type === 'lookup') {
|
|
73
|
+
ASSERT(f.entity,
|
|
74
|
+
`BLOCKING: ${res.code} lookup field "${f.field}" missing entity`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// CHECK 7: Computed attributes are readonly or absent (WARNING)
|
|
82
|
+
if (res.type === 'SmartForm' && res.tabs) {
|
|
83
|
+
const compAttrs = computedAttrs[res.entity] || [];
|
|
84
|
+
for (const tab of res.tabs) {
|
|
85
|
+
if (tab.fields) {
|
|
86
|
+
for (const f of tab.fields) {
|
|
87
|
+
if (compAttrs.includes(f.field) && !f.readonly) {
|
|
88
|
+
WARN(`${res.code} field "${f.field}" is computed but not readonly`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// CHECK 8: SmartFilter filters reference valid fields + lookup entity
|
|
96
|
+
if (res.type === 'SmartFilter' && res.filters) {
|
|
97
|
+
for (const filter of res.filters) {
|
|
98
|
+
if (filter.type === 'lookup') {
|
|
99
|
+
ASSERT(filter.entity,
|
|
100
|
+
`BLOCKING: ${res.code} filter "${filter.field}" type lookup missing entity`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// CHECK 9: SmartFilter mandatory for list sections with SmartTable (BLOCKING)
|
|
108
|
+
for (const section of screens.sections) {
|
|
109
|
+
if (section.sectionCode === 'list') {
|
|
110
|
+
const hasTable = section.resources.some(r => r.type === 'SmartTable');
|
|
111
|
+
const hasFilter = section.resources.some(r => r.type === 'SmartFilter');
|
|
112
|
+
if (hasTable && !hasFilter && !mod.code.includes('Portal')) {
|
|
113
|
+
ASSERT(false, `BLOCKING: ${mod.code}.list has SmartTable but no SmartFilter`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// CHECK 10: SmartKanban for workflow entities (WARNING)
|
|
119
|
+
for (const e of entities.entities) {
|
|
120
|
+
const statusAttr = e.attributes.find(a => a.name === 'status' && a.type === 'enum');
|
|
121
|
+
if (statusAttr && (statusAttr.options || []).length >= 3 && !mod.code.includes('Portal')) {
|
|
122
|
+
const hasKanban = screens.sections.some(s =>
|
|
123
|
+
s.resources.some(r => r.type === 'SmartKanban' && r.entity === e.name)
|
|
124
|
+
);
|
|
125
|
+
if (!hasKanban) {
|
|
126
|
+
WARN(`${mod.code}: entity "${e.name}" has ${statusAttr.options.length} workflow states but no SmartKanban`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Validation Checklist
|
|
134
|
+
|
|
135
|
+
Run these checks after writing all screens.json files:
|
|
136
|
+
|
|
137
|
+
- [ ] Every resource has a valid `entity` referencing an entity from entities.json
|
|
138
|
+
- [ ] Every resource has a valid `permission` referencing permissions.json
|
|
139
|
+
- [ ] Every SmartTable column references a valid entity attribute
|
|
140
|
+
- [ ] Every SmartForm field references a valid entity attribute
|
|
141
|
+
- [ ] Every SmartTable `rowActions[]` has `action` and `permission` fields
|
|
142
|
+
- [ ] Every section has at least one resource
|
|
143
|
+
- [ ] Every module has at least one section
|
|
144
|
+
- [ ] Every lookup field (SmartForm + SmartFilter) has an `entity` property
|
|
145
|
+
- [ ] Computed attributes are `readonly: true` in detail forms or absent from create forms
|
|
146
|
+
- [ ] Every `list` section with SmartTable also has a SmartFilter (except Portal)
|
|
147
|
+
- [ ] Every entity with `status` enum >= 3 options has a SmartKanban resource (except Portal/config)
|
|
148
|
+
|
|
149
|
+
## Check Details
|
|
150
|
+
|
|
151
|
+
### CHECK 1: Section Resources
|
|
152
|
+
Every section MUST have at least one resource. Empty sections are invalid.
|
|
153
|
+
|
|
154
|
+
**Error Format:** `BLOCKING: {module}.{sectionCode} has 0 resources`
|
|
155
|
+
|
|
156
|
+
### CHECK 2: Entity References
|
|
157
|
+
Every resource MUST reference a valid entity name from entities.json.
|
|
158
|
+
|
|
159
|
+
**Error Format:** `BLOCKING: {resource.code} references unknown entity "{entity}"`
|
|
160
|
+
|
|
161
|
+
### CHECK 3: Permission References
|
|
162
|
+
Every resource MUST have a permission field.
|
|
163
|
+
|
|
164
|
+
**Error Format:** `BLOCKING: {resource.code} missing permission`
|
|
165
|
+
|
|
166
|
+
### CHECK 4: SmartTable Column Attributes
|
|
167
|
+
Every column in a SmartTable MUST reference a valid attribute from the entity. Nested attributes (e.g., `department.name`) are split on the first dot.
|
|
168
|
+
|
|
169
|
+
**Error Format:** `BLOCKING: {resource.code} column "{field}" not in {entity}`
|
|
170
|
+
|
|
171
|
+
### CHECK 5: SmartForm Field Attributes
|
|
172
|
+
Every field in a SmartForm tab MUST reference a valid attribute from the entity.
|
|
173
|
+
|
|
174
|
+
**Error Format:** `BLOCKING: {resource.code} field "{field}" not in {entity}`
|
|
175
|
+
|
|
176
|
+
### CHECK 6: Lookup Field Entity References
|
|
177
|
+
Every lookup field in a SmartForm MUST include an `entity` property identifying the target entity.
|
|
178
|
+
|
|
179
|
+
**Error Format:** `BLOCKING: {resource.code} lookup field "{field}" missing entity`
|
|
180
|
+
|
|
181
|
+
### CHECK 7: Computed Attribute Readonly (WARNING)
|
|
182
|
+
Computed attributes (marked `computed: true` in entities.json) appearing in SmartForm SHOULD have `readonly: true`. This is a warning, not blocking.
|
|
183
|
+
|
|
184
|
+
**Warning Format:** `{resource.code} field "{field}" is computed but not readonly`
|
|
185
|
+
|
|
186
|
+
### CHECK 8: SmartFilter Lookup Entity References
|
|
187
|
+
Every lookup filter in a SmartFilter MUST include an `entity` property.
|
|
188
|
+
|
|
189
|
+
**Error Format:** `BLOCKING: {resource.code} filter "{field}" type lookup missing entity`
|
|
190
|
+
|
|
191
|
+
### CHECK 9: SmartFilter Mandatory for Lists
|
|
192
|
+
Every `list` section with a SmartTable MUST also include a SmartFilter resource (except for Portal modules).
|
|
193
|
+
|
|
194
|
+
**Error Format:** `BLOCKING: {module}.list has SmartTable but no SmartFilter`
|
|
195
|
+
|
|
196
|
+
### CHECK 10: SmartKanban Workflow Detection (WARNING)
|
|
197
|
+
Every entity with a `status` enum attribute having 3 or more options (except Portal/config modules) SHOULD have a SmartKanban resource. This is a warning, not blocking.
|
|
198
|
+
|
|
199
|
+
**Warning Format:** `{module}: entity "{entity}" has {count} workflow states but no SmartKanban`
|
|
200
|
+
|
|
201
|
+
## Error Resolution
|
|
202
|
+
|
|
203
|
+
### BLOCKING Errors
|
|
204
|
+
Stop immediately and fix these errors before proceeding to step-02:
|
|
205
|
+
|
|
206
|
+
1. Add missing resources to empty sections
|
|
207
|
+
2. Verify entity names match entities.json exactly (case-sensitive)
|
|
208
|
+
3. Add permission properties to all resources
|
|
209
|
+
4. Fix column/field names to match entity attributes
|
|
210
|
+
5. Add entity properties to all lookup fields
|
|
211
|
+
6. Add SmartFilter to list sections with SmartTable
|
|
212
|
+
|
|
213
|
+
### WARNING Errors
|
|
214
|
+
Review and fix if applicable, but these do not block progress:
|
|
215
|
+
|
|
216
|
+
1. Add `readonly: true` to computed fields in forms
|
|
217
|
+
2. Consider adding SmartKanban for workflow entities with status enums
|
|
218
|
+
|
|
219
|
+
## Exit Criteria
|
|
220
|
+
|
|
221
|
+
All BLOCKING checks must pass before proceeding to step-02. WARNING checks should be reviewed and fixed where applicable.
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Screens Type Mapping & Business Rules
|
|
2
|
+
|
|
3
|
+
This document defines how entity attributes map to UI component field types and specifies the business rules for handling computed attributes, readonly fields, lookups, and workflow detection.
|
|
4
|
+
|
|
5
|
+
## Column/Field Type Mapping
|
|
6
|
+
|
|
7
|
+
Map entity attribute types to SmartTable columns and SmartForm fields:
|
|
8
|
+
|
|
9
|
+
| Entity type | SmartTable type | SmartForm type |
|
|
10
|
+
|-------------|----------------|----------------|
|
|
11
|
+
| `string` | `text` | `text` |
|
|
12
|
+
| `int`, `decimal` | `number` | `number` |
|
|
13
|
+
| `date` | `date` | `datepicker` |
|
|
14
|
+
| `datetime` | `datetime` | `datetimepicker` |
|
|
15
|
+
| `bool` | `boolean` | `checkbox` |
|
|
16
|
+
| `enum` | `badge` | `select` |
|
|
17
|
+
| `guid` (FK) | `lookup` | `lookup` |
|
|
18
|
+
| `text` (long) | `text` (truncated) | `textarea` |
|
|
19
|
+
|
|
20
|
+
## Computed Attribute Rule
|
|
21
|
+
|
|
22
|
+
If `entities.json` marks an attribute with `computed: true`:
|
|
23
|
+
|
|
24
|
+
- **SmartForm detail/edit:** the field MUST have `readonly: true`
|
|
25
|
+
- **SmartForm create:** the field MUST be ABSENT (not yet calculable)
|
|
26
|
+
- **SmartTable:** the field can appear normally (read-only by nature)
|
|
27
|
+
|
|
28
|
+
Example:
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"field": "totalCompensation",
|
|
32
|
+
"label": "Salaire Total",
|
|
33
|
+
"type": "number",
|
|
34
|
+
"readonly": true
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Readonly Field Rule
|
|
39
|
+
|
|
40
|
+
- `readonly` MUST be a boolean (`true` or `false`)
|
|
41
|
+
- Do NOT use string values like `"onCreate"` or `"onEdit"`
|
|
42
|
+
- For conditional readonly logic (e.g., readonly on create but editable on edit), use a business rule (BR-WF category) to express the condition
|
|
43
|
+
- The form always shows `readonly: true` or omits the field entirely
|
|
44
|
+
|
|
45
|
+
Valid:
|
|
46
|
+
```json
|
|
47
|
+
{ "field": "status", "readonly": false }
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Invalid:
|
|
51
|
+
```json
|
|
52
|
+
{ "field": "status", "readonly": "onCreate" }
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## SmartForm Section Location Rule
|
|
56
|
+
|
|
57
|
+
- **SmartForm in `list` section:** inline create / quick-create drawer (user creates without leaving the list)
|
|
58
|
+
- **SmartForm in `detail` section:** full edit page (user navigates to a dedicated form page)
|
|
59
|
+
|
|
60
|
+
Both patterns are valid. Use `list` section for high-frequency data entry (e.g., time entries). Use `detail` section for complex entities with multiple tabs.
|
|
61
|
+
|
|
62
|
+
## Lookup Field Rule
|
|
63
|
+
|
|
64
|
+
Lookup fields require explicit entity references for downstream consumers to resolve the foreign key target.
|
|
65
|
+
|
|
66
|
+
**SmartForm requirement:**
|
|
67
|
+
> Every SmartForm field with `type: "lookup"` MUST include `"entity": "{TargetEntityName}"`
|
|
68
|
+
|
|
69
|
+
Example:
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"field": "department",
|
|
73
|
+
"label": "Departement",
|
|
74
|
+
"type": "lookup",
|
|
75
|
+
"entity": "Department",
|
|
76
|
+
"required": true
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**SmartFilter requirement:**
|
|
81
|
+
> Every SmartFilter filter with `type: "lookup"` MUST include `"entity": "{TargetEntityName}"`
|
|
82
|
+
|
|
83
|
+
Example:
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"field": "departmentId",
|
|
87
|
+
"type": "lookup",
|
|
88
|
+
"label": "Departement",
|
|
89
|
+
"entity": "Department"
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## SmartKanban Auto-Detection Rule (OBLIGATOIRE)
|
|
94
|
+
|
|
95
|
+
For each entity with an `enum` attribute named `status` having >= 3 options:
|
|
96
|
+
|
|
97
|
+
- **ADD** a SmartKanban resource in a dedicated `kanban` section (or alongside SmartTable in `list`)
|
|
98
|
+
- **MAP** each enum option to a Kanban column with appropriate color:
|
|
99
|
+
- `gray` = draft/pending
|
|
100
|
+
- `blue` = submitted/in progress
|
|
101
|
+
- `green` = approved/completed
|
|
102
|
+
- `red` = rejected/cancelled
|
|
103
|
+
- `orange` = warning/under review
|
|
104
|
+
- **SET** `cardFields` to the 3-4 most relevant display attributes (typically: code, name/label, assignee, date)
|
|
105
|
+
- **SKIP** for:
|
|
106
|
+
- Portal modules (read-only, no workflow)
|
|
107
|
+
- Config/lookup entities (static, no workflow)
|
|
108
|
+
|
|
109
|
+
Example detection:
|
|
110
|
+
```javascript
|
|
111
|
+
const statusAttr = entity.attributes.find(
|
|
112
|
+
a => a.name === 'status' && a.type === 'enum'
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
if (statusAttr && (statusAttr.options || []).length >= 3 && !isPortalModule) {
|
|
116
|
+
// ADD SmartKanban resource
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
This ensures workflow entities get a visual board view — the standard UX for approval/lifecycle processes.
|
|
121
|
+
|
|
122
|
+
## SmartFilter Mandatory Rule
|
|
123
|
+
|
|
124
|
+
Every `list` section with a SmartTable MUST also have a SmartFilter resource placed BEFORE the SmartTable.
|
|
125
|
+
|
|
126
|
+
**Pattern:**
|
|
127
|
+
```
|
|
128
|
+
Section: list
|
|
129
|
+
Resource 1: SmartFilter (filters come first)
|
|
130
|
+
Resource 2: SmartTable (grid follows)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Do NOT embed `filters[]` inside SmartTable — use a dedicated SmartFilter resource instead.
|
|
134
|
+
|
|
135
|
+
**Exceptions (SKIP SmartFilter for):**
|
|
136
|
+
- Portal modules with a single read-only grid
|
|
137
|
+
|
|
138
|
+
This ensures consistent filtering UX across all data lists.
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# SmartComponent JSON Templates Reference
|
|
2
|
+
|
|
3
|
+
This document contains the canonical JSON schema examples for all SmartComponent types used in screens definition. These templates show the exact structure and required fields for each component.
|
|
4
|
+
|
|
5
|
+
## SmartTable Template
|
|
6
|
+
|
|
7
|
+
A data grid component for displaying and managing entity collections with sorting, filtering, and row-level actions.
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"code": "{entity-plural}-grid",
|
|
12
|
+
"type": "SmartTable",
|
|
13
|
+
"entity": "{EntityName}",
|
|
14
|
+
"label": "Grille des {entity-plural}",
|
|
15
|
+
"columns": [
|
|
16
|
+
{ "field": "code", "label": "Code", "type": "text", "sortable": true, "width": "100px" },
|
|
17
|
+
{ "field": "fullName", "label": "Nom", "type": "text", "sortable": true },
|
|
18
|
+
{ "field": "department.name", "label": "Departement", "type": "lookup", "filterable": true },
|
|
19
|
+
{ "field": "status", "label": "Statut", "type": "badge", "filterable": true, "options": ["Active", "Inactive"] }
|
|
20
|
+
],
|
|
21
|
+
"actions": ["create", "edit", "delete", "export"],
|
|
22
|
+
"permission": "{AppCode}.{ModuleCode}.Read",
|
|
23
|
+
"rowActions": [
|
|
24
|
+
{ "action": "edit", "permission": "{AppCode}.{ModuleCode}.Update" },
|
|
25
|
+
{ "action": "view-detail", "permission": "{AppCode}.{ModuleCode}.Read" }
|
|
26
|
+
],
|
|
27
|
+
"defaultSort": { "field": "code", "direction": "asc" },
|
|
28
|
+
"pageSize": 25
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## SmartForm Template
|
|
33
|
+
|
|
34
|
+
A form component for creating and editing entity records with support for multiple tabs, field validation, and nested subtables.
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"code": "{entity}-form",
|
|
39
|
+
"type": "SmartForm",
|
|
40
|
+
"entity": "{EntityName}",
|
|
41
|
+
"label": "Fiche {entity}",
|
|
42
|
+
"tabs": [
|
|
43
|
+
{
|
|
44
|
+
"label": "Informations",
|
|
45
|
+
"fields": [
|
|
46
|
+
{ "field": "firstName", "label": "Prenom", "type": "text", "required": true, "col": 6 },
|
|
47
|
+
{ "field": "lastName", "label": "Nom", "type": "text", "required": true, "col": 6 },
|
|
48
|
+
{ "field": "email", "label": "Email", "type": "email", "required": true, "validation": "unique" },
|
|
49
|
+
{ "field": "department", "label": "Departement", "type": "lookup", "entity": "Department", "required": true },
|
|
50
|
+
{ "field": "status", "label": "Statut", "type": "select", "options": ["Active", "Inactive"], "readonly": false }
|
|
51
|
+
]
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"label": "Contrats",
|
|
55
|
+
"type": "subtable",
|
|
56
|
+
"entity": "Contract",
|
|
57
|
+
"columns": ["contractType", "startDate", "endDate", "status"]
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
"permission": "{AppCode}.{ModuleCode}.Update"
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## SmartDashboard Template
|
|
65
|
+
|
|
66
|
+
A dashboard component for displaying key performance indicators (KPIs) and data visualizations via charts.
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"code": "{module}-dashboard",
|
|
71
|
+
"type": "SmartDashboard",
|
|
72
|
+
"entity": "{PrimaryEntityName}",
|
|
73
|
+
"label": "Tableau de bord {module}",
|
|
74
|
+
"kpis": [
|
|
75
|
+
{ "label": "Total actifs", "value": "count(status=Active)", "icon": "users", "color": "primary" },
|
|
76
|
+
{ "label": "En conge", "value": "count(status=OnLeave)", "icon": "calendar", "color": "warning" }
|
|
77
|
+
],
|
|
78
|
+
"charts": [
|
|
79
|
+
{ "type": "pie", "label": "Repartition par departement", "dataSource": "employees", "groupBy": "department" },
|
|
80
|
+
{ "type": "bar", "label": "Evolution des effectifs", "dataSource": "employees", "groupBy": "hireDate.year" }
|
|
81
|
+
],
|
|
82
|
+
"permission": "{AppCode}.{ModuleCode}.Read"
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## SmartKanban Template
|
|
87
|
+
|
|
88
|
+
A board component for workflow-based entities with status columns and draggable cards.
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"code": "{entity}-kanban",
|
|
93
|
+
"type": "SmartKanban",
|
|
94
|
+
"entity": "{EntityName}",
|
|
95
|
+
"label": "Kanban {entity}",
|
|
96
|
+
"statusField": "status",
|
|
97
|
+
"columns": [
|
|
98
|
+
{ "value": "Draft", "label": "Brouillon", "color": "gray" },
|
|
99
|
+
{ "value": "Submitted", "label": "Soumis", "color": "blue" },
|
|
100
|
+
{ "value": "Approved", "label": "Approuve", "color": "green" }
|
|
101
|
+
],
|
|
102
|
+
"cardFields": ["code", "assignee", "dueDate"],
|
|
103
|
+
"permission": "{AppCode}.{ModuleCode}.Read"
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## SmartFilter Template
|
|
108
|
+
|
|
109
|
+
A dedicated filter component placed before SmartTable in list sections. Do NOT embed filters inside SmartTable — use a separate SmartFilter resource instead.
|
|
110
|
+
|
|
111
|
+
```json
|
|
112
|
+
{
|
|
113
|
+
"code": "{entity-plural}-filters",
|
|
114
|
+
"type": "SmartFilter",
|
|
115
|
+
"entity": "{EntityName}",
|
|
116
|
+
"label": "Filtres {entity-plural}",
|
|
117
|
+
"filters": [
|
|
118
|
+
{ "field": "status", "type": "select", "label": "Statut", "options": ["Active", "Inactive"] },
|
|
119
|
+
{ "field": "departmentId", "type": "lookup", "label": "Departement", "entity": "Department" },
|
|
120
|
+
{ "field": "startDate", "type": "daterange", "label": "Periode" },
|
|
121
|
+
{ "field": "search", "type": "text", "label": "Recherche" }
|
|
122
|
+
],
|
|
123
|
+
"permission": "{AppCode}.{ModuleCode}.Read"
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## SmartCard Template
|
|
128
|
+
|
|
129
|
+
A card component for displaying entity summaries with avatar, title, subtitle, and action buttons.
|
|
130
|
+
|
|
131
|
+
```json
|
|
132
|
+
{
|
|
133
|
+
"code": "{entity}-card",
|
|
134
|
+
"type": "SmartCard",
|
|
135
|
+
"entity": "{EntityName}",
|
|
136
|
+
"label": "Carte {entity}",
|
|
137
|
+
"title": "fullName",
|
|
138
|
+
"subtitle": "position",
|
|
139
|
+
"fields": [
|
|
140
|
+
{ "field": "email", "label": "Email", "icon": "mail" },
|
|
141
|
+
{ "field": "department.name", "label": "Departement", "icon": "building" }
|
|
142
|
+
],
|
|
143
|
+
"avatar": "profileImage",
|
|
144
|
+
"actions": ["view-detail", "edit"],
|
|
145
|
+
"permission": "{AppCode}.{ModuleCode}.Read"
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Canonical Output Format (screens.json)
|
|
150
|
+
|
|
151
|
+
The final screens.json file MUST use the sections[] wrapper format:
|
|
152
|
+
|
|
153
|
+
```json
|
|
154
|
+
{
|
|
155
|
+
"sections": [
|
|
156
|
+
{
|
|
157
|
+
"sectionCode": "list",
|
|
158
|
+
"sectionLabel": "Liste des employes",
|
|
159
|
+
"resources": [
|
|
160
|
+
{
|
|
161
|
+
"code": "employees-filters",
|
|
162
|
+
"type": "SmartFilter",
|
|
163
|
+
"entity": "Employee",
|
|
164
|
+
"label": "Filtres employes",
|
|
165
|
+
"filters": [
|
|
166
|
+
{ "field": "departmentId", "type": "lookup", "label": "Departement", "entity": "Department" },
|
|
167
|
+
{ "field": "status", "type": "select", "label": "Statut", "options": ["Active", "Inactive"] }
|
|
168
|
+
],
|
|
169
|
+
"permission": "HumanResources.Employees.Read"
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"code": "employees-grid",
|
|
173
|
+
"type": "SmartTable",
|
|
174
|
+
"entity": "Employee",
|
|
175
|
+
"label": "Grille des employes",
|
|
176
|
+
"columns": [],
|
|
177
|
+
"actions": ["create", "export"],
|
|
178
|
+
"rowActions": [
|
|
179
|
+
{ "action": "edit", "permission": "HumanResources.Employees.Update" },
|
|
180
|
+
{ "action": "view-detail", "permission": "HumanResources.Employees.Read" }
|
|
181
|
+
],
|
|
182
|
+
"permission": "HumanResources.Employees.Read"
|
|
183
|
+
}
|
|
184
|
+
]
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"sectionCode": "detail",
|
|
188
|
+
"sectionLabel": "Fiche employe",
|
|
189
|
+
"resources": [
|
|
190
|
+
{
|
|
191
|
+
"code": "employee-form",
|
|
192
|
+
"type": "SmartForm",
|
|
193
|
+
"entity": "Employee",
|
|
194
|
+
"label": "Fiche employe",
|
|
195
|
+
"tabs": [],
|
|
196
|
+
"actions": ["save", "cancel"],
|
|
197
|
+
"permission": "HumanResources.Employees.Update"
|
|
198
|
+
}
|
|
199
|
+
]
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"sectionCode": "dashboard",
|
|
203
|
+
"sectionLabel": "Tableau de bord",
|
|
204
|
+
"resources": [
|
|
205
|
+
{
|
|
206
|
+
"code": "employees-dashboard",
|
|
207
|
+
"type": "SmartDashboard",
|
|
208
|
+
"entity": "Employee",
|
|
209
|
+
"label": "Tableau de bord RH",
|
|
210
|
+
"kpis": [],
|
|
211
|
+
"charts": [],
|
|
212
|
+
"permission": "HumanResources.Employees.Read"
|
|
213
|
+
}
|
|
214
|
+
]
|
|
215
|
+
}
|
|
216
|
+
]
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Key Naming Requirements
|
|
221
|
+
|
|
222
|
+
- Use `sectionCode` (not `id` or `code`)
|
|
223
|
+
- Use `sectionLabel` (not `displayName` or `label`)
|
|
224
|
+
- Resource `type` must be one of: `SmartTable`, `SmartForm`, `SmartDashboard`, `SmartKanban`, `SmartCard`, `SmartFilter`
|
|
225
|
+
- The flat `screens[]` format (one object per screen with componentType at top level) is **DEPRECATED** — use `sections[]` instead
|