@atlashub/smartstack-cli 3.54.0 → 4.0.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 +1748 -780
- package/dist/index.js.map +1 -1
- package/dist/mcp-entry.mjs +850 -172
- package/dist/mcp-entry.mjs.map +1 -1
- package/package.json +115 -115
- package/templates/skills/apex/SKILL.md +11 -9
- package/templates/skills/apex/references/agent-teams-protocol.md +32 -16
- package/templates/skills/apex/references/core-seed-data.md +1 -1
- package/templates/skills/apex/references/smartstack-api.md +6 -0
- package/templates/skills/apex/references/smartstack-layers.md +125 -118
- package/templates/skills/apex/steps/step-02-plan.md +33 -18
- package/templates/skills/apex/steps/step-03-execute.md +297 -120
- package/templates/skills/apex/steps/step-04-examine.md +15 -6
- package/templates/skills/apex/steps/step-07-tests.md +60 -40
- package/templates/skills/apex/steps/step-08-run-tests.md +5 -3
|
@@ -16,8 +16,8 @@ All code goes through skills (/controller, /application, /ui-components, /efcore
|
|
|
16
16
|
> **CONTEXT REUSE:** `smartstack-api.md` (loaded in step-01) and `smartstack-layers.md` (loaded in step-02) are already in context. Do NOT re-read them.
|
|
17
17
|
|
|
18
18
|
- **ALWAYS** read `references/smartstack-frontend.md` — lazy loading, i18n, page structure, CSS variables, EntityLookup, compliance gates (sections 1-9)
|
|
19
|
-
-
|
|
20
|
-
- If `{
|
|
19
|
+
- **ALWAYS** read `references/core-seed-data.md` — comprehensive seed data templates (Layer 1)
|
|
20
|
+
- If NOT `{economy_mode}` AND a layer has multi-entity work: read `references/agent-teams-protocol.md`
|
|
21
21
|
- If build failure during execution: read `references/error-classification.md` — error diagnosis categories A-F
|
|
22
22
|
|
|
23
23
|
---
|
|
@@ -30,9 +30,10 @@ This is a foundation-only execution (called by ralph-loop Phase 0). Execute ONLY
|
|
|
30
30
|
- Layer 0: Domain entities + EF configs + Migration
|
|
31
31
|
|
|
32
32
|
**SKIP ALL OTHER LAYERS:**
|
|
33
|
-
- Layer 1:
|
|
34
|
-
- Layer 2:
|
|
35
|
-
- Layer 3:
|
|
33
|
+
- Layer 1: Seed Data → SKIP
|
|
34
|
+
- Layer 2: Backend → SKIP
|
|
35
|
+
- Layer 3: Frontend → SKIP
|
|
36
|
+
- Layer 4: DevData → SKIP
|
|
36
37
|
|
|
37
38
|
After Layer 0 completes and builds successfully:
|
|
38
39
|
- Commit with message: `chore(foundation): entities for {module_code}`
|
|
@@ -40,7 +41,7 @@ After Layer 0 completes and builds successfully:
|
|
|
40
41
|
- End execution
|
|
41
42
|
|
|
42
43
|
**IF `{foundation_mode}` == false:**
|
|
43
|
-
Execute ALL layers normally (Layer 0 → Layer 1 → Layer 2 → Layer 3).
|
|
44
|
+
Execute ALL layers normally (Layer 0 → Layer 1 → Layer 2 → Layer 3 → Layer 4).
|
|
44
45
|
|
|
45
46
|
---
|
|
46
47
|
|
|
@@ -107,137 +108,233 @@ dotnet build
|
|
|
107
108
|
|
|
108
109
|
**MUST PASS before Layer 1. If NuGet error, run `dotnet restore` first. If file lock (MSB3021), use `--output /tmp/{project}_build`.**
|
|
109
110
|
|
|
111
|
+
### Layer 0 Commit
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
feat({module}): [domain+infra] {short description}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Layer 1 — Seed Data (DEDICATED LAYER — sequential, agent principal)
|
|
120
|
+
|
|
121
|
+
> **This layer is DEDICATED and MANDATORY.** Seed data makes modules visible in the UI.
|
|
122
|
+
> Without seed data, the module exists in code but is invisible to users.
|
|
123
|
+
> Reference: `references/core-seed-data.md` (loaded above) for complete C# templates.
|
|
124
|
+
|
|
125
|
+
### Application-Level Seed Data (ONCE per application)
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
1. NavigationApplicationSeedData.cs
|
|
129
|
+
→ Application-level navigation entry (MUST be first)
|
|
130
|
+
→ Random GUID via Guid.NewGuid()
|
|
131
|
+
→ 4 language translations (fr, en, it, de)
|
|
132
|
+
|
|
133
|
+
2. ApplicationRolesSeedData.cs
|
|
134
|
+
→ 4 roles: admin, manager, contributor, viewer
|
|
135
|
+
→ Random GUIDs (Guid.NewGuid())
|
|
136
|
+
→ References NavigationApplicationSeedData.ApplicationId
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Per-Module Seed Data
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
3. NavigationModuleSeedData.cs
|
|
143
|
+
→ Random GUIDs (Guid.NewGuid()), 4 languages (fr, en, it, de)
|
|
144
|
+
→ GetModuleEntry() + GetTranslationEntries()
|
|
145
|
+
→ If sections defined: GetSectionEntries() + GetSectionTranslationEntries()
|
|
146
|
+
→ If resources defined: GetResourceEntries() + resource translations
|
|
147
|
+
→ Query actual parent from DB for FK (NOT deterministic GUID)
|
|
148
|
+
|
|
149
|
+
4. Permissions.cs
|
|
150
|
+
→ MCP generate_permissions (PRIMARY tool)
|
|
151
|
+
→ Static constants: public static class {Module} { public const string Read = "..."; }
|
|
152
|
+
→ Permission paths MUST use kebab-case matching NavRoute codes
|
|
153
|
+
|
|
154
|
+
5. PermissionsSeedData.cs
|
|
155
|
+
→ MCP generate_permissions first, fallback template
|
|
156
|
+
→ Paths match Permissions.cs, wildcard + CRUD
|
|
157
|
+
|
|
158
|
+
6. RolesSeedData.cs
|
|
159
|
+
→ Admin=wildcard(*), Manager=CRU, Contributor=CR, Viewer=R
|
|
160
|
+
→ Code-based role mapping (NEVER deterministic GUIDs for roles)
|
|
161
|
+
→ Look up roles by Code at runtime
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Infrastructure Provider (ONCE per application)
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
7. {App}SeedDataProvider.cs
|
|
168
|
+
→ Implements IClientSeedDataProvider
|
|
169
|
+
→ SeedNavigationAsync(): Application → Module → Section → Resource + translations
|
|
170
|
+
→ SeedRolesAsync(): application-scoped roles from ApplicationRolesSeedData
|
|
171
|
+
→ SeedPermissionsAsync(): permission entries from PermissionsSeedData
|
|
172
|
+
→ SeedRolePermissionsAsync(): maps roles to permissions (by Code, NOT by GUID)
|
|
173
|
+
→ DI: services.AddScoped<IClientSeedDataProvider, {App}SeedDataProvider>()
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Post-Layer 1 Build Gate
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
dotnet build
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**MUST PASS before Layer 2.**
|
|
183
|
+
|
|
184
|
+
### Layer 1 Commit
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
feat({module}): [seed] navigation, permissions, roles
|
|
188
|
+
```
|
|
189
|
+
|
|
110
190
|
---
|
|
111
191
|
|
|
112
|
-
## Layer
|
|
192
|
+
## Layer 2 — Backend (Services + Controllers)
|
|
113
193
|
|
|
114
|
-
> **Layer
|
|
115
|
-
> - NavRoute and permission kebab-case (Layer
|
|
194
|
+
> **Layer 2 rules** are in `references/smartstack-layers.md` (already in context from step-02):
|
|
195
|
+
> - NavRoute and permission kebab-case (Layer 2 - API section)
|
|
116
196
|
> - Controller route attributes (FORBIDDEN: [Route] alongside [NavRoute])
|
|
117
197
|
> - Validators DI registration
|
|
118
198
|
> - DateOnly vs string for DTO date fields
|
|
119
199
|
> - Code generation patterns (ICodeGenerator<T> registration, see references/code-generation.md)
|
|
120
200
|
|
|
121
|
-
### Backend Tasks (sequential or parallel)
|
|
201
|
+
### Backend Tasks (sequential or parallel within layer)
|
|
122
202
|
|
|
123
203
|
- **Services/DTOs:** MCP scaffold_extension
|
|
124
204
|
- **Controllers:** use /controller skill for complex, MCP scaffold_extension for simple
|
|
125
205
|
- **IMPORTANT:** ALL GetAll endpoints MUST support `?search=` query parameter (enables EntityLookup on frontend)
|
|
126
|
-
- **Seed data:** MCP generate_permissions, then follow smartstack-layers.md templates
|
|
127
206
|
|
|
128
|
-
###
|
|
207
|
+
### Skill Delegation
|
|
129
208
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
> - Section-level routes and permissions — section 3b
|
|
139
|
-
> - I18n JSON structure and registration — section 2
|
|
140
|
-
> - Compliance gates (5 mandatory checks) — section 9
|
|
209
|
+
| Skill | When | Context to provide |
|
|
210
|
+
|-------|------|--------------------|
|
|
211
|
+
| /controller | Custom routes, complex auth, file upload | entity, CRUD actions, permissions, routes |
|
|
212
|
+
| /application | Full app/module from scratch | app, module names |
|
|
213
|
+
| /ui-components | Complex pages (tables, grids, dashboards) | entity, fields, page type |
|
|
214
|
+
| /efcore | Complex EF configs, inheritance | relationships, indexes |
|
|
215
|
+
| /notification | In-app or email notifications | trigger, recipients, template |
|
|
216
|
+
| /workflow | Automated workflows | trigger, steps, conditions |
|
|
141
217
|
|
|
142
|
-
### If NOT economy_mode: Agent Teams (parallel)
|
|
218
|
+
### If NOT economy_mode AND multiple entities: Agent Teams (parallel within layer)
|
|
143
219
|
|
|
144
220
|
> **Protocol:** See `references/agent-teams-protocol.md`
|
|
145
221
|
|
|
146
222
|
```
|
|
147
|
-
TeamCreate("apex-
|
|
148
|
-
|
|
149
|
-
Spawn 2 teammates (Opus, full tools):
|
|
223
|
+
TeamCreate("apex-layer2", description: "Execute Layer 2 backend in parallel")
|
|
150
224
|
|
|
151
|
-
1
|
|
152
|
-
"Execute these Layer 1 backend tasks for module {module_code}:
|
|
153
|
-
{list of application + api + seed data tasks from plan}
|
|
225
|
+
Spawn 1 teammate per entity (Opus, full tools):
|
|
154
226
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
-
|
|
158
|
-
-
|
|
159
|
-
-
|
|
227
|
+
For each entity:
|
|
228
|
+
Task: "Execute Layer 2 backend for entity {EntityName}:
|
|
229
|
+
- Application service/DTO: MCP scaffold_extension
|
|
230
|
+
- Controller: /controller skill or MCP scaffold_extension
|
|
231
|
+
- IMPORTANT: GetAll endpoint MUST support ?search= parameter
|
|
232
|
+
- Validators: FluentValidation + DI registration
|
|
160
233
|
|
|
161
234
|
After ALL tasks done:
|
|
162
|
-
SendMessage(type:'message', recipient:'team-lead', content:'
|
|
235
|
+
SendMessage(type:'message', recipient:'team-lead', content:'ENTITY_COMPLETE: {EntityName}', summary:'{EntityName} backend done')"
|
|
163
236
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
237
|
+
Wait for all teammates to report completion.
|
|
238
|
+
shutdown_request → shutdown_response → TeamDelete("apex-layer2")
|
|
239
|
+
```
|
|
167
240
|
|
|
168
|
-
|
|
241
|
+
### Post-Layer 2 Build Gate
|
|
169
242
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
- Pages: use /ui-components skill — MUST follow smartstack-frontend.md patterns:
|
|
174
|
-
→ React.lazy() for all page imports (named export wrapping)
|
|
175
|
-
→ <Suspense fallback={<PageLoader />}> around all lazy components
|
|
176
|
-
→ Page structure: hooks → useEffect(load) → loading → error → content
|
|
177
|
-
→ CSS variables only: bg-[var(--bg-card)], text-[var(--text-primary)]
|
|
178
|
-
→ SmartTable/SmartFilter/EntityCard (NEVER raw HTML)
|
|
179
|
-
- **FORM PAGES (CRITICAL):** Create/Edit forms are FULL PAGES with own routes:
|
|
180
|
-
→ EntityCreatePage.tsx with route /{module}/create
|
|
181
|
-
→ EntityEditPage.tsx with route /{module}/:id/edit
|
|
182
|
-
→ ZERO modals/popups/drawers/dialogs for forms
|
|
183
|
-
→ Back button with navigate(-1) on every form page
|
|
184
|
-
→ See smartstack-frontend.md section 3b for templates
|
|
185
|
-
- **TABS ON DETAIL PAGES (CRITICAL):** Tabs MUST switch content LOCALLY:
|
|
186
|
-
→ Tab click handler: setActiveTab(tabKey) ONLY — NEVER navigate() to another page
|
|
187
|
-
→ Tab content: render inline with {activeTab === 'tabKey' && <TabContent />}
|
|
188
|
-
→ Sub-resource data: fetch via API filtered by parent ID, display in tab panel
|
|
189
|
-
→ FORBIDDEN: navigate('../leaves?employee=${id}') in tab handler
|
|
190
|
-
→ See smartstack-frontend.md section 3 'Tab Behavior Rules'
|
|
191
|
-
- **FK FIELDS (CRITICAL):** Foreign key Guid fields (e.g., EmployeeId) MUST use EntityLookup:
|
|
192
|
-
→ NEVER render FK fields as `<input>` — users cannot type GUIDs
|
|
193
|
-
→ NEVER render FK fields as `<select>` — even with API-loaded options, `<select>` is NOT acceptable
|
|
194
|
-
→ ONLY use `<EntityLookup />` from @/components/ui/EntityLookup for searchable selection
|
|
195
|
-
→ Each FK field needs: apiEndpoint, mapOption (display name), search support on backend
|
|
196
|
-
→ FORBIDDEN: `<select value={formData.departmentId}>`, `<option value={dept.id}>`, `e.target.value` for FK fields
|
|
197
|
-
→ See smartstack-frontend.md section 6 for the full EntityLookup pattern
|
|
198
|
-
- **FORM TESTS (MANDATORY):**
|
|
199
|
-
→ EntityCreatePage.test.tsx (co-located next to page)
|
|
200
|
-
→ EntityEditPage.test.tsx (co-located next to page)
|
|
201
|
-
→ Cover: rendering, validation, submit, pre-fill, navigation, errors
|
|
202
|
-
→ See smartstack-frontend.md section 8 for test templates
|
|
203
|
-
- **PERMISSIONS:** Call MCP generate_permissions for the module permission root (2 segments: {app}.{module}),
|
|
204
|
-
then also call MCP generate_permissions for EACH section (3 segments: {app}.{module}.{section}).
|
|
205
|
-
- **SECTION ROUTES:** Add section child routes to the module's children array.
|
|
206
|
-
Wire PermissionGuard for section routes with section-level permissions.
|
|
207
|
-
- I18n: Generate 4 JSON files per module namespace (fr, en, it, de)
|
|
208
|
-
→ Follow JSON template from smartstack-frontend.md
|
|
209
|
-
→ Keys: actions, labels, errors, validation, columns, form, messages, empty
|
|
210
|
-
→ ALL t() calls MUST use namespace prefix + fallback: t('ns:key', 'Default text')
|
|
211
|
-
- MUST use src/pages/{App}/{Module}/ hierarchy (NOT flat)
|
|
243
|
+
```bash
|
|
244
|
+
dotnet build
|
|
245
|
+
```
|
|
212
246
|
|
|
213
|
-
|
|
214
|
-
SendMessage(type:'message', recipient:'team-lead', content:'FRONTEND_COMPLETE', summary:'Frontend layer done')"
|
|
247
|
+
**MUST PASS before backend tests.**
|
|
215
248
|
|
|
216
|
-
|
|
249
|
+
### Backend Tests Inline
|
|
217
250
|
|
|
218
|
-
|
|
219
|
-
dotnet build (backend)
|
|
220
|
-
npm run typecheck (frontend, if applicable)
|
|
251
|
+
> **Tests are scaffolded and run WITHIN Layer 2, not deferred to step-07.**
|
|
221
252
|
|
|
222
|
-
|
|
253
|
+
```
|
|
254
|
+
1. Scaffold backend tests:
|
|
255
|
+
→ MCP scaffold_tests (target_layer: "domain", module: "{module_code}", test_type: "unit")
|
|
256
|
+
→ MCP scaffold_tests (target_layer: "application", module: "{module_code}", test_type: "unit")
|
|
257
|
+
→ MCP scaffold_tests (target_layer: "api", module: "{module_code}", test_type: "integration")
|
|
258
|
+
|
|
259
|
+
2. Run tests:
|
|
260
|
+
dotnet test --no-build --verbosity normal
|
|
261
|
+
|
|
262
|
+
3. Fix loop (max 3 iterations):
|
|
263
|
+
IF tests fail:
|
|
264
|
+
→ Identify root cause (ALWAYS code bug, not test bug)
|
|
265
|
+
→ Fix production CODE via appropriate skill/MCP
|
|
266
|
+
→ dotnet build --no-restore
|
|
267
|
+
→ dotnet test --no-build
|
|
268
|
+
→ Repeat until pass or max 3
|
|
269
|
+
|
|
270
|
+
4. If still failing after 3 iterations: note failures, continue to Layer 3.
|
|
271
|
+
Step-07 "Final Test Sweep" will handle remaining failures.
|
|
223
272
|
```
|
|
224
273
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
## Layer 1 — Skill Delegation
|
|
274
|
+
### Layer 2 Commits
|
|
228
275
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
| /ui-components | Complex pages (tables, grids, dashboards) | entity, fields, page type |
|
|
234
|
-
| /efcore | Complex EF configs, inheritance | relationships, indexes |
|
|
235
|
-
| /notification | In-app or email notifications | trigger, recipients, template |
|
|
236
|
-
| /workflow | Automated workflows | trigger, steps, conditions |
|
|
276
|
+
```
|
|
277
|
+
feat({module}): [app+api] {short description}
|
|
278
|
+
test({module}): backend unit and integration tests
|
|
279
|
+
```
|
|
237
280
|
|
|
238
281
|
---
|
|
239
282
|
|
|
240
|
-
## Layer
|
|
283
|
+
## Layer 3 — Frontend (Pages + I18n + Documentation)
|
|
284
|
+
|
|
285
|
+
> **Frontend patterns** are in `references/smartstack-frontend.md` (already loaded above):
|
|
286
|
+
> - API client generation (MCP scaffold_api_client)
|
|
287
|
+
> - Route scaffolding (MCP scaffold_routes) — section 1 + 3b
|
|
288
|
+
> - Page types (ListPage, DetailPage, CreatePage, EditPage) — section 3
|
|
289
|
+
> - FK field handling (EntityLookup component) — section 6
|
|
290
|
+
> - Form structure (ZERO modals — all full pages) — section 3b
|
|
291
|
+
> - Detail page tabs (local state only) — section 3 "Tab Behavior Rules"
|
|
292
|
+
> - Testing patterns (co-located form tests) — section 8
|
|
293
|
+
> - Section-level routes and permissions — section 3b
|
|
294
|
+
> - I18n JSON structure and registration — section 2
|
|
295
|
+
> - Compliance gates (5 mandatory checks) — section 9
|
|
296
|
+
|
|
297
|
+
### Frontend Tasks (sequential or parallel within layer)
|
|
298
|
+
|
|
299
|
+
For each module:
|
|
300
|
+
- **API client:** MCP scaffold_api_client
|
|
301
|
+
- **Routes:** MCP scaffold_routes (outputFormat: 'clientRoutes') → generates lazy imports + Suspense
|
|
302
|
+
- **Pages:** use /ui-components skill — MUST follow smartstack-frontend.md patterns:
|
|
303
|
+
→ React.lazy() for all page imports (named export wrapping)
|
|
304
|
+
→ `<Suspense fallback={<PageLoader />}>` around all lazy components
|
|
305
|
+
→ Page structure: hooks → useEffect(load) → loading → error → content
|
|
306
|
+
→ CSS variables only: bg-[var(--bg-card)], text-[var(--text-primary)]
|
|
307
|
+
→ SmartTable/SmartFilter/EntityCard (NEVER raw HTML)
|
|
308
|
+
- **FORM PAGES (CRITICAL):** Create/Edit forms are FULL PAGES with own routes:
|
|
309
|
+
→ EntityCreatePage.tsx with route /{module}/create
|
|
310
|
+
→ EntityEditPage.tsx with route /{module}/:id/edit
|
|
311
|
+
→ ZERO modals/popups/drawers/dialogs for forms
|
|
312
|
+
→ Back button with navigate(-1) on every form page
|
|
313
|
+
→ See smartstack-frontend.md section 3b for templates
|
|
314
|
+
- **TABS ON DETAIL PAGES (CRITICAL):** Tabs MUST switch content LOCALLY:
|
|
315
|
+
→ Tab click handler: setActiveTab(tabKey) ONLY — NEVER navigate() to another page
|
|
316
|
+
→ Tab content: render inline with {activeTab === 'tabKey' && <TabContent />}
|
|
317
|
+
→ Sub-resource data: fetch via API filtered by parent ID, display in tab panel
|
|
318
|
+
→ FORBIDDEN: navigate('../leaves?employee=${id}') in tab handler
|
|
319
|
+
→ See smartstack-frontend.md section 3 'Tab Behavior Rules'
|
|
320
|
+
- **FK FIELDS (CRITICAL):** Foreign key Guid fields (e.g., EmployeeId) MUST use EntityLookup:
|
|
321
|
+
→ NEVER render FK fields as `<input>` — users cannot type GUIDs
|
|
322
|
+
→ NEVER render FK fields as `<select>` — even with API-loaded options, `<select>` is NOT acceptable
|
|
323
|
+
→ ONLY use `<EntityLookup />` from @/components/ui/EntityLookup for searchable selection
|
|
324
|
+
→ Each FK field needs: apiEndpoint, mapOption (display name), search support on backend
|
|
325
|
+
→ FORBIDDEN: `<select value={formData.departmentId}>`, `<option value={dept.id}>`, `e.target.value` for FK fields
|
|
326
|
+
→ See smartstack-frontend.md section 6 for the full EntityLookup pattern
|
|
327
|
+
- **I18n:** Generate 4 JSON files per module namespace (fr, en, it, de)
|
|
328
|
+
→ Follow JSON template from smartstack-frontend.md
|
|
329
|
+
→ Keys: actions, labels, errors, validation, columns, form, messages, empty
|
|
330
|
+
→ ALL t() calls MUST use namespace prefix + fallback: t('ns:key', 'Default text')
|
|
331
|
+
- **PERMISSIONS:** Call MCP generate_permissions for the module permission root (2 segments: {app}.{module}),
|
|
332
|
+
then also call MCP generate_permissions for EACH section (3 segments: {app}.{module}.{section}).
|
|
333
|
+
- **SECTION ROUTES:** Add section child routes to the module's children array.
|
|
334
|
+
Wire PermissionGuard for section routes with section-level permissions.
|
|
335
|
+
- MUST use src/pages/{App}/{Module}/ hierarchy (NOT flat)
|
|
336
|
+
|
|
337
|
+
### Documentation (after frontend pages exist)
|
|
241
338
|
|
|
242
339
|
> **After frontend pages are created, generate module documentation via `/documentation` skill.**
|
|
243
340
|
|
|
@@ -257,28 +354,35 @@ This generates:
|
|
|
257
354
|
- Import: `import { DocToggleButton } from '@/components/docs/DocToggleButton';`
|
|
258
355
|
- Placement: inside the header actions area (see `smartstack-frontend.md` section 7)
|
|
259
356
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
## Layer 2 — Final Seed Data + Validation (sequential)
|
|
357
|
+
### If NOT economy_mode AND multiple entities: Agent Teams (parallel within layer)
|
|
263
358
|
|
|
264
|
-
|
|
359
|
+
> **Protocol:** See `references/agent-teams-protocol.md`
|
|
265
360
|
|
|
266
361
|
```
|
|
267
|
-
|
|
268
|
-
- NavigationModuleSeedData.cs with 4 languages
|
|
269
|
-
- PermissionsSeedData.cs with Guid.NewGuid()
|
|
270
|
-
- RolesSeedData.cs with context-based role mapping
|
|
271
|
-
- IClientSeedDataProvider updated
|
|
272
|
-
- DI registration added
|
|
362
|
+
TeamCreate("apex-layer3", description: "Execute Layer 3 frontend in parallel")
|
|
273
363
|
|
|
274
|
-
|
|
275
|
-
dotnet build → MUST PASS
|
|
276
|
-
npm run typecheck → MUST PASS (if frontend)
|
|
277
|
-
```
|
|
364
|
+
Spawn 1 teammate per entity (Opus, full tools):
|
|
278
365
|
|
|
279
|
-
|
|
366
|
+
For each entity:
|
|
367
|
+
Task: "Execute Layer 3 frontend for entity {EntityName}:
|
|
368
|
+
**MANDATORY: Read references/smartstack-frontend.md FIRST**
|
|
369
|
+
- API client: MCP scaffold_api_client
|
|
370
|
+
- Routes: MCP scaffold_routes (outputFormat: 'clientRoutes')
|
|
371
|
+
- Pages: /ui-components skill (ALL 4 types: List, Detail, Create, Edit)
|
|
372
|
+
- I18n: 4 JSON files (fr, en, it, de)
|
|
373
|
+
- FORM PAGES: Full pages with own routes (ZERO modals)
|
|
374
|
+
- FK FIELDS: EntityLookup for all FK Guid fields
|
|
375
|
+
- TABS: Local state only (NEVER navigate())
|
|
376
|
+
- FORM TESTS: Co-located .test.tsx for Create and Edit pages
|
|
377
|
+
|
|
378
|
+
After ALL tasks done:
|
|
379
|
+
SendMessage(type:'message', recipient:'team-lead', content:'ENTITY_COMPLETE: {EntityName}', summary:'{EntityName} frontend done')"
|
|
280
380
|
|
|
281
|
-
|
|
381
|
+
Wait for all teammates to report completion.
|
|
382
|
+
shutdown_request → shutdown_response → TeamDelete("apex-layer3")
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### FRONTEND COMPLIANCE GATE (MANDATORY before commit)
|
|
282
386
|
|
|
283
387
|
> **Reference:** See `references/smartstack-frontend.md` section 9 "Compliance Gates" for all 5 mandatory checks:
|
|
284
388
|
> 1. CSS Variables (theme system)
|
|
@@ -294,6 +398,74 @@ When delegating to `/ui-components` skill, include explicit instructions:
|
|
|
294
398
|
- "Forms: Create/Edit forms are FULL PAGES with own routes (e.g., `/create`, `/:id/edit`)."
|
|
295
399
|
- "I18n: ALL text must use `t('namespace:key', 'Fallback')`. Generate JSON files in `src/i18n/locales/`."
|
|
296
400
|
|
|
401
|
+
### Frontend Tests Inline
|
|
402
|
+
|
|
403
|
+
> **Tests are scaffolded and run WITHIN Layer 3, not deferred to step-07.**
|
|
404
|
+
|
|
405
|
+
```
|
|
406
|
+
1. Scaffold frontend tests:
|
|
407
|
+
→ For each module with create/edit pages:
|
|
408
|
+
→ Generate EntityCreatePage.test.tsx and EntityEditPage.test.tsx
|
|
409
|
+
→ Co-located next to the page component (NOT in __tests__/ folder)
|
|
410
|
+
→ Cover: rendering, validation, submit, pre-fill, navigation, errors
|
|
411
|
+
→ Tools: Vitest + React Testing Library + @testing-library/user-event
|
|
412
|
+
→ Mock API: vi.mock() or MSW — NEVER real API calls
|
|
413
|
+
|
|
414
|
+
2. Run tests:
|
|
415
|
+
WEB_DIR=$(find . -name "vitest.config.ts" -not -path "*/node_modules/*" -exec dirname {} \; 2>/dev/null | head -1)
|
|
416
|
+
if [ -n "$WEB_DIR" ]; then
|
|
417
|
+
(cd "$WEB_DIR" && npm run test)
|
|
418
|
+
fi
|
|
419
|
+
|
|
420
|
+
3. Fix loop (max 3 iterations):
|
|
421
|
+
IF tests fail:
|
|
422
|
+
→ Identify root cause (ALWAYS code bug, not test bug)
|
|
423
|
+
→ Fix production CODE
|
|
424
|
+
→ Re-run tests
|
|
425
|
+
→ Repeat until pass or max 3
|
|
426
|
+
|
|
427
|
+
4. If still failing after 3 iterations: note failures, continue.
|
|
428
|
+
Step-07 "Final Test Sweep" will handle remaining failures.
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### Typecheck Gate
|
|
432
|
+
|
|
433
|
+
```bash
|
|
434
|
+
npm run typecheck
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
**MUST PASS before commit.**
|
|
438
|
+
|
|
439
|
+
### Layer 3 Commits
|
|
440
|
+
|
|
441
|
+
```
|
|
442
|
+
feat({module}): [frontend] pages, routes, i18n, documentation
|
|
443
|
+
test({module}): frontend form tests
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
## Layer 4 — DevData (optional)
|
|
449
|
+
|
|
450
|
+
> **Business test data for development/demo environments.**
|
|
451
|
+
> Skip this layer if no meaningful test data is needed.
|
|
452
|
+
|
|
453
|
+
```
|
|
454
|
+
1. Create DevDataSeeder:
|
|
455
|
+
→ Infrastructure/Persistence/Seeding/DevData/{Module}DevDataSeeder.cs
|
|
456
|
+
→ ALL entities MUST include TenantId
|
|
457
|
+
→ Realistic business data for demo purposes
|
|
458
|
+
|
|
459
|
+
2. Build gate:
|
|
460
|
+
dotnet build → MUST PASS
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### Layer 4 Commit (if applicable)
|
|
464
|
+
|
|
465
|
+
```
|
|
466
|
+
feat({module}): [devdata] test data for development
|
|
467
|
+
```
|
|
468
|
+
|
|
297
469
|
---
|
|
298
470
|
|
|
299
471
|
## PRD State Update (delegate mode only)
|
|
@@ -323,11 +495,16 @@ After each layer completes, gates pass, and builds pass:
|
|
|
323
495
|
|
|
324
496
|
```
|
|
325
497
|
Layer 0: feat({module}): [domain+infra] {short description}
|
|
326
|
-
Layer 1: feat({module}): [
|
|
327
|
-
Layer
|
|
328
|
-
Layer 2:
|
|
498
|
+
Layer 1: feat({module}): [seed] navigation, permissions, roles
|
|
499
|
+
Layer 2: feat({module}): [app+api] {short description}
|
|
500
|
+
Layer 2: test({module}): backend unit and integration tests
|
|
501
|
+
Layer 3: feat({module}): [frontend] pages, routes, i18n, documentation
|
|
502
|
+
Layer 3: test({module}): frontend form tests
|
|
503
|
+
Layer 4: feat({module}): [devdata] test data for development # if applicable
|
|
329
504
|
```
|
|
330
505
|
|
|
506
|
+
**Maximum 7 commits per module.**
|
|
507
|
+
|
|
331
508
|
---
|
|
332
509
|
|
|
333
510
|
## Save Output (if save_mode)
|
|
@@ -225,6 +225,14 @@ AC2: {criterion} → PASS / FAIL (evidence: {file:line or test})
|
|
|
225
225
|
```
|
|
226
226
|
**APEX SmartStack - eXamine Complete**
|
|
227
227
|
|
|
228
|
+
| Layer | Status | Details |
|
|
229
|
+
|-------|--------|---------|
|
|
230
|
+
| Layer 0 — Domain + Infrastructure | PASS / N/A | Entities, EF configs, migration, build gate |
|
|
231
|
+
| Layer 1 — Seed Data | PASS / N/A | Navigation, permissions, roles, provider, build gate |
|
|
232
|
+
| Layer 2 — Backend | PASS / N/A | Services, controllers, build gate, inline tests |
|
|
233
|
+
| Layer 3 — Frontend | PASS / N/A | Pages, i18n, docs, compliance gate, inline tests |
|
|
234
|
+
| Layer 4 — DevData | PASS / N/A / SKIPPED | Optional test data |
|
|
235
|
+
|
|
228
236
|
| Category | Checks | Status |
|
|
229
237
|
|----------|--------|--------|
|
|
230
238
|
| MCP conventions | validate_conventions | PASS (0 errors) |
|
|
@@ -244,6 +252,8 @@ AC2: {criterion} → PASS / FAIL (evidence: {file:line or test})
|
|
|
244
252
|
| Role-permission matrix | Admin=wildcard, Manager=CRU, Contributor=CR, Viewer=R (POST-CHECK 42) | PASS / N/A |
|
|
245
253
|
| PermissionAction enum | No Enum.Parse, only typed enum values 0-10 (POST-CHECK 43) | PASS / N/A |
|
|
246
254
|
| Navigation translations | 4 langs per level, section/resource translations present (POST-CHECK 44) | PASS / N/A |
|
|
255
|
+
| Inline tests (Layer 2) | Backend unit + integration tests | PASS / N/A |
|
|
256
|
+
| Inline tests (Layer 3) | Frontend form tests | PASS / N/A |
|
|
247
257
|
| POST-CHECKs | 3 MCP tools + 50 bash checks (6 security + 44 convention) | PASS / N/A |
|
|
248
258
|
| Acceptance criteria | AC1..ACn | {X}/{Y} PASS |
|
|
249
259
|
```
|
|
@@ -256,24 +266,23 @@ Write to `{output_dir}/04-examine.md` with validation results.
|
|
|
256
266
|
|
|
257
267
|
---
|
|
258
268
|
|
|
259
|
-
## 10. Route to Next Step —
|
|
269
|
+
## 10. Route to Next Step — FINAL TEST SWEEP
|
|
260
270
|
|
|
261
|
-
> **
|
|
262
|
-
> Step-
|
|
263
|
-
> Completing APEX without tests violates the methodology — skip is FORBIDDEN.
|
|
271
|
+
> **Note:** Backend tests (Layer 2) and frontend tests (Layer 3) have already been scaffolded and run inline.
|
|
272
|
+
> Step-07 "Final Test Sweep" handles: security tests, coverage analysis, cross-layer scenarios, and remaining failures.
|
|
264
273
|
|
|
265
274
|
```
|
|
266
275
|
IF examine_mode (-x flag):
|
|
267
276
|
→ Load steps/step-05-deep-review.md (adversarial review)
|
|
268
277
|
→ Then step-06 (resolve) if BLOCKING findings
|
|
269
|
-
→ Then step-07 (
|
|
278
|
+
→ Then step-07 (Final Test Sweep) — ALWAYS
|
|
270
279
|
|
|
271
280
|
ELSE:
|
|
272
281
|
→ Load steps/step-07-tests.md — IMMEDIATELY after eXamine completes
|
|
273
282
|
```
|
|
274
283
|
|
|
275
284
|
**BLOCKING RULE:** The APEX workflow is NOT complete until steps 07-08 execute.
|
|
276
|
-
The success criteria require: "Tests: 100% pass, >= 80% coverage" —
|
|
285
|
+
The success criteria require: "Tests: 100% pass, >= 80% coverage" — step-07 verifies coverage and adds security tests.
|
|
277
286
|
|
|
278
287
|
**NEXT ACTION:** Load `steps/step-07-tests.md` now.
|
|
279
288
|
|