@atlashub/smartstack-cli 4.32.0 → 4.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/.documentation/index.html +2 -2
  2. package/.documentation/init.html +358 -174
  3. package/dist/index.js +45 -0
  4. package/dist/index.js.map +1 -1
  5. package/dist/mcp-entry.mjs +271 -44
  6. package/dist/mcp-entry.mjs.map +1 -1
  7. package/package.json +1 -1
  8. package/templates/mcp-scaffolding/controller.cs.hbs +54 -128
  9. package/templates/project/README.md +19 -0
  10. package/templates/project/claude-md/api.CLAUDE.md.template +315 -0
  11. package/templates/project/claude-md/application.CLAUDE.md.template +181 -0
  12. package/templates/project/claude-md/domain.CLAUDE.md.template +125 -0
  13. package/templates/project/claude-md/infrastructure.CLAUDE.md.template +168 -0
  14. package/templates/project/claude-md/root.CLAUDE.md.template +339 -0
  15. package/templates/project/claude-md/web.CLAUDE.md.template +339 -0
  16. package/templates/skills/apex/SKILL.md +16 -10
  17. package/templates/skills/apex/_shared.md +1 -1
  18. package/templates/skills/apex/references/checks/architecture-checks.sh +154 -0
  19. package/templates/skills/apex/references/checks/backend-checks.sh +194 -0
  20. package/templates/skills/apex/references/checks/frontend-checks.sh +448 -0
  21. package/templates/skills/apex/references/checks/infrastructure-checks.sh +255 -0
  22. package/templates/skills/apex/references/checks/security-checks.sh +153 -0
  23. package/templates/skills/apex/references/checks/seed-checks.sh +536 -0
  24. package/templates/skills/apex/references/frontend-route-wiring-app-tsx.md +49 -192
  25. package/templates/skills/apex/references/post-checks.md +124 -2156
  26. package/templates/skills/apex/references/smartstack-api.md +160 -957
  27. package/templates/skills/apex/references/smartstack-frontend.md +134 -1022
  28. package/templates/skills/apex/references/smartstack-layers.md +12 -6
  29. package/templates/skills/apex/steps/step-00-init.md +81 -238
  30. package/templates/skills/apex/steps/step-03-execute.md +25 -752
  31. package/templates/skills/apex/steps/step-03a-layer0-domain.md +118 -0
  32. package/templates/skills/apex/steps/step-03b-layer1-seed.md +91 -0
  33. package/templates/skills/apex/steps/step-03c-layer2-backend.md +240 -0
  34. package/templates/skills/apex/steps/step-03d-layer3-frontend.md +300 -0
  35. package/templates/skills/apex/steps/step-03e-layer4-devdata.md +44 -0
  36. package/templates/skills/apex/steps/step-04-examine.md +70 -150
  37. package/templates/skills/application/references/frontend-i18n-and-output.md +2 -2
  38. package/templates/skills/application/references/frontend-route-naming.md +5 -1
  39. package/templates/skills/application/references/frontend-route-wiring-app-tsx.md +49 -198
  40. package/templates/skills/application/references/frontend-verification.md +11 -11
  41. package/templates/skills/application/steps/step-05-frontend.md +26 -15
  42. package/templates/skills/application/templates-frontend.md +4 -0
  43. package/templates/skills/cli-app-sync/SKILL.md +2 -2
  44. package/templates/skills/cli-app-sync/references/comparison-map.md +1 -1
  45. package/templates/skills/controller/references/controller-code-templates.md +70 -67
  46. package/templates/skills/controller/references/mcp-scaffold-workflow.md +5 -1
@@ -0,0 +1,300 @@
1
+ ---
2
+ name: step-03d-layer3-frontend
3
+ description: "Layer 3: Frontend pages, i18n, routes, documentation, and tests"
4
+ model: opus
5
+ parent_step: steps/step-03-execute.md
6
+ ---
7
+
8
+ # Layer 3 — Frontend (Pages + I18n + Documentation)
9
+
10
+ ### ⛔ HARD RULE — /ui-components is NON-NEGOTIABLE (read BEFORE any Layer 3 action)
11
+
12
+ > **VIOLATION CHECK:** If ANY .tsx page file was created by Write tool WITHOUT
13
+ > a prior Skill("ui-components") call in this execution, the frontend layer is INVALID.
14
+ >
15
+ > **You MUST NOT:**
16
+ > - Generate .tsx page code in Agent prompts and dispatch to Snipper agents
17
+ > - Write page content directly via the Write tool
18
+ > - Copy-paste page templates from your knowledge
19
+ >
20
+ > **You MUST:**
21
+ > - Call Skill("ui-components") which loads the style guide, responsive guidelines,
22
+ > accessibility rules, and pattern files (entity-card, data-table, dashboard-chart, grid-layout, kanban)
23
+ > - Let /ui-components generate all pages with correct conventions
24
+ >
25
+ > **Why this matters:** Without the skill, pages miss CSS variables, DataTable/EntityCard,
26
+ > memo()/useCallback, responsive mobile-first design, and accessibility patterns.
27
+ >
28
+ > **Agent boundary rule:** Snipper sub-agents DO NOT have access to the Skill tool.
29
+ > Therefore, .tsx page generation MUST NEVER be delegated to Snipper agents.
30
+ > Pages are ALWAYS generated by the principal agent via Skill("ui-components").
31
+ > Snipper agents handle: API clients, routes, wiring, i18n, tests — NOT pages.
32
+
33
+ ### Load Frontend References (deferred from top of step)
34
+
35
+ - Read `references/smartstack-frontend.md` now — lazy loading, i18n, page structure, CSS variables, EntityLookup (sections 1-6)
36
+ - Read `references/smartstack-frontend-compliance.md` now — documentation, form testing, compliance gates (sections 7-9)
37
+
38
+ ### Pre-flight: Shared component existence check
39
+
40
+ Before generating any page, verify shared components exist:
41
+
42
+ ```
43
+ Glob("src/components/ui/DataTable.*")
44
+ Glob("src/components/ui/EntityCard.*")
45
+ Glob("src/components/ui/PageLoader.*")
46
+ Glob("src/components/ui/EntityLookup.*")
47
+ ```
48
+
49
+ If ANY shared component is MISSING:
50
+ → Log warning: "Shared component {Component} not found — will be generated locally"
51
+ → When invoking Skill("ui-components"), add instruction:
52
+ "MISSING SHARED COMPONENTS: {list}. Generate these locally in src/components/ui/"
53
+
54
+ **EntityLookup special handling (FK fields):**
55
+ If ANY entity has FK Guid fields (e.g., EmployeeId, DepartmentId) AND EntityLookup is missing:
56
+ → Include EntityLookup generation in the Skill("ui-components") invocation
57
+ → Add to the skill prompt: "MISSING SHARED COMPONENT: EntityLookup. Generate EntityLookup in src/components/ui/EntityLookup.tsx"
58
+ → The /ui-components skill has the EntityLookup pattern in smartstack-frontend.md section 6
59
+ → Critical requirement for the skill: response parsing MUST use `(res.data.items || res.data).map(mapOption)`
60
+ → Verify after generation: the component MUST contain `(res.data.items || res.data).map(mapOption)` — if not, fix it
61
+ → Do NOT generate EntityLookup manually via Write tool — always via Skill("ui-components")
62
+
63
+ ### Task Progress
64
+ TaskUpdate(taskId: layer3_task_id, status: "in_progress")
65
+ TaskUpdate(taskId: progress_tracker_id,
66
+ description: "Module: {module_code}. Current: step-03 (Execute), Layer 3",
67
+ activeForm: "Executing Layer 3")
68
+
69
+ > **Frontend patterns** are in `references/smartstack-frontend.md` (already loaded above):
70
+ > - API client generation (MCP scaffold_api_client)
71
+ > - Route scaffolding (MCP scaffold_routes) — section 1 + 3b
72
+ > - Page types (ListPage, DetailPage, CreatePage, EditPage) — section 3
73
+ > - FK field handling (EntityLookup component) — section 6
74
+ > - Form structure (no modals — all full pages) — section 3b
75
+ > - Detail page tabs (local state only) — section 3 "Tab Behavior Rules"
76
+ > - Testing patterns (co-located form tests) — section 8
77
+ > - Section-level routes and permissions — section 3b
78
+ > - I18n JSON structure and registration — section 2
79
+ > - Compliance gates (5 mandatory checks) — section 9
80
+
81
+ ### Frontend Tasks (sequential or parallel within layer)
82
+
83
+ For each module:
84
+ - API client: MCP scaffold_api_client
85
+ - Routes — TWO mandatory steps:
86
+ 1. Generate registry: MCP scaffold_routes (source: 'controllers', outputFormat: 'componentRegistry', dryRun: false)
87
+ → Creates/updates componentRegistry.generated.ts + navRoutes.generated.ts
88
+ 2. Verify PageRegistry registration (see below)
89
+ - Pages per section: When a section exists (e.g., "list"), generate ALL 4 page types:
90
+ → {Section}ListPage.tsx (index route)
91
+ → {Section}DetailPage.tsx (/:id route) — click on list item navigates here
92
+ → Create{Section}Page.tsx (/create route)
93
+ → Edit{Section}Page.tsx (/:id/edit route)
94
+ "detail" is NEVER a separate section — it's the /:id route of the list section.
95
+ - Pages: **MANDATORY — INVOKE Skill("ui-components")** for ALL page generation.
96
+ ⚠ BLOCKING REQUIREMENT: You MUST call Skill("ui-components") for EVERY page (.tsx).
97
+ NEVER generate .tsx page code directly. NEVER write page content in Agent prompts.
98
+ NEVER use Write tool to create pages without first calling Skill("ui-components").
99
+ The skill loads the full style guide + patterns (entity-card, data-table, dashboard-chart, grid-layout).
100
+ Follow smartstack-frontend.md patterns:
101
+ → React.lazy() for all page imports (named export wrapping)
102
+ → `<Suspense fallback={<PageLoader />}>` around all lazy components
103
+ → Page structure: hooks → useEffect(load) → loading → error → content
104
+ → CSS variables only: bg-[var(--bg-card)], text-[var(--text-primary)]
105
+ → DataTable/EntityCard (not raw HTML `<table>`)
106
+ → If entity has FK Guid fields: generate EntityLookup component in @/components/ui/EntityLookup (see smartstack-frontend.md section 6)
107
+ → Dashboard pages: generate StatCard + ChartCard locally (see ui-components patterns/dashboard-chart.md)
108
+ - Form pages: Create/Edit forms are full pages with own routes:
109
+ → EntityCreatePage.tsx with route /{module}/create
110
+ → EntityEditPage.tsx with route /{module}/:id/edit
111
+ → Zero modals/popups/drawers/dialogs for forms
112
+ → Back button with navigate(-1) on every form page
113
+ → See smartstack-frontend.md section 3b for templates
114
+ - Tabs on detail pages: Tabs must switch content locally:
115
+ → Tab click handler: setActiveTab(tabKey) only — do not navigate() to another page
116
+ → Tab content: render inline with {activeTab === 'tabKey' && <TabContent />}
117
+ → Sub-resource data: fetch via API filtered by parent ID, display in tab panel
118
+ → Do not use navigate('../leaves?employee=${id}') in tab handler
119
+ → See smartstack-frontend.md section 3 'Tab Behavior Rules'
120
+ - FK fields: Foreign key Guid fields (e.g., EmployeeId) must use EntityLookup:
121
+ → Do not render FK fields as `<input>` — users cannot type GUIDs
122
+ → Do not render FK fields as `<select>` — even with API-loaded options, `<select>` is not acceptable
123
+ → Only use `<EntityLookup />` from @/components/ui/EntityLookup for searchable selection
124
+ → Each FK field needs: apiEndpoint, mapOption (display name), search support on backend
125
+ → Do not use `<select value={formData.departmentId}>`, `<option value={dept.id}>`, `e.target.value` for FK fields
126
+ → See smartstack-frontend.md section 6 for the full EntityLookup pattern
127
+ <!-- TODO A12: Replace direct i18n generation with MCP scaffold_i18n when B4 is ready -->
128
+ - I18n: Generate 4 JSON files per module namespace (fr, en, it, de)
129
+ → Follow JSON template from smartstack-frontend.md
130
+ → Keys: actions, labels, errors, validation, columns, form, messages, empty
131
+ → All t() calls must use namespace prefix + fallback: t('ns:key', 'Default text')
132
+ → **Register namespace in i18n config** (critical — POST-CHECK C39 catches this, but fix it now):
133
+ 1. Find i18n config: `Glob("src/**/i18n/config.ts")` or `index.ts` or `i18n.ts`
134
+ 2. Read the config → find the resources/ns registration pattern
135
+ 3. Add the new namespace import + registration for all 4 languages
136
+ 4. If config uses dynamic imports: add namespace to the `ns` array
137
+ 5. Verify: `grep -q "{module_namespace}" src/**/i18n/config.ts` → must match
138
+ - Permissions: Call MCP generate_permissions for the module permission root (2 segments: {app}.{module}),
139
+ then also call MCP generate_permissions for each section (3 segments: {app}.{module}.{section}).
140
+ - Section routes: Ensure navigation seed data has ComponentKey matching PageRegistry keys.
141
+ ComponentKey convention: `{app_code}.{module_code}.{section_code}` (dot-separated, lowercase).
142
+ DynamicRouter generates the URL paths from seed data Route field.
143
+ - MUST use src/pages/{App}/{Module}/ hierarchy (NOT flat)
144
+
145
+ ### Documentation (after frontend pages exist)
146
+
147
+ > **After frontend pages are created, generate module documentation via `/documentation` skill.**
148
+
149
+ ```
150
+ Invoke /documentation {module_code} --type user
151
+
152
+ This generates:
153
+ - src/pages/docs/business/{app}/{module}/doc-data.ts (data file)
154
+ - src/pages/docs/business/{app}/{module}/index.tsx (page wrapper)
155
+ - src/i18n/locales/fr/docs-{app}-{module}.json (French doc translations)
156
+ - Updates App.tsx routing for doc page
157
+ - Updates docs-manifest.json
158
+ ```
159
+
160
+ **Verify DocToggleButton presence in list/detail pages:**
161
+ - Every `*ListPage.tsx` and `*DetailPage.tsx` MUST import and render `DocToggleButton` in their header
162
+ - Import: `import { DocToggleButton } from '@/components/docs/DocToggleButton';`
163
+ - Placement: inside the header actions area (see `smartstack-frontend.md` section 7)
164
+
165
+ ### If NOT economy_mode AND multiple entities: Parallel Agents (within layer)
166
+
167
+ > **Protocol:** See `references/parallel-execution.md`
168
+
169
+ ```
170
+ IF NOT economy_mode AND entities.length > 1:
171
+ # PHASE A — Parallel: infrastructure frontend (NO page generation)
172
+ # Snipper agents DO NOT have access to the Skill tool, so they CANNOT call /ui-components.
173
+ # Pages MUST be generated by the principal agent in Phase B.
174
+ For each entity, launch in parallel (single message):
175
+ Agent(subagent_type='Snipper', model='opus',
176
+ prompt='Execute Layer 3 INFRASTRUCTURE for {EntityName}:
177
+ **MANDATORY: Read references/smartstack-frontend.md FIRST**
178
+ - API client: MCP scaffold_api_client
179
+ - Routes: MCP scaffold_routes (outputFormat: "componentRegistry", dryRun: false)
180
+ → MUST generate componentRegistry.generated.ts + navRoutes.generated.ts
181
+ - Verify: componentRegistry.generated.ts has PageRegistry.register() for new pages
182
+ - Verify: main.tsx imports componentRegistry.generated (one-time check)
183
+ - NO manual App.tsx wiring needed — DynamicRouter handles routing
184
+ - I18n: 4 JSON files (fr, en, it, de) + REGISTER namespace in i18n config
185
+ - DO NOT generate any .tsx page files — pages are handled by the principal agent
186
+ - Your task ID is {task_id}. Call TaskUpdate(status: "in_progress") before starting.
187
+ - Call TaskUpdate(status: "completed", metadata: { files_created: [...] }) when done.')
188
+ # Wait for all agents to complete
189
+
190
+ # PHASE B — Sequential: pages via /ui-components (principal agent)
191
+ # Snipper agents cannot call Skill() — only the principal agent can.
192
+ For each entity (sequentially):
193
+ **INVOKE Skill("ui-components")** — pass entity context:
194
+ - Entity: {EntityName}, Module: {ModuleName}, App: {AppName}
195
+ - Page types: List, Detail, Create, Edit (+ Dashboard if applicable)
196
+ - "CSS: Use CSS variables ONLY — bg-[var(--bg-card)], text-[var(--text-primary)]"
197
+ - "Forms: Create/Edit are FULL PAGES with own routes (/create, /:id/edit)"
198
+ - "FK FIELDS: EntityLookup for ALL FK Guid fields"
199
+ - "I18n: ALL text uses t('namespace:key', 'Fallback')"
200
+ Generate form tests: co-located .test.tsx for Create and Edit pages
201
+
202
+ ELSE:
203
+ # Economy mode: Agent principal handles all entities SEQUENTIALLY.
204
+ # MANDATORY: You MUST still call Skill("ui-components") for page generation.
205
+ # economy_mode only disables parallel agents — it does NOT skip /ui-components.
206
+ For each entity (sequentially):
207
+ 1. MCP scaffold_api_client
208
+ 2. MCP scaffold_routes (outputFormat: 'componentRegistry')
209
+ 3. Verify PageRegistry registration (componentRegistry.generated.ts)
210
+ No manual App.tsx wiring needed — DynamicRouter resolves at runtime
211
+ 4. **INVOKE Skill("ui-components")** — pass entity context:
212
+ - Entity: {EntityName}, Module: {ModuleName}, App: {AppName}
213
+ - Page types: List, Detail, Create, Edit (+ Dashboard if applicable)
214
+ - "CSS: Use CSS variables ONLY — bg-[var(--bg-card)], text-[var(--text-primary)]"
215
+ - "Forms: Create/Edit are FULL PAGES with own routes (/create, /:id/edit)"
216
+ - "I18n: ALL text uses t('namespace:key', 'Fallback')"
217
+ 5. I18n: 4 JSON files (fr, en, it, de) + register namespace in i18n config
218
+ 6. Form tests: co-located .test.tsx for Create and Edit pages
219
+ ```
220
+
221
+ ### Parallel Agents + TaskCreate Integration
222
+
223
+ When launching agents for multi-entity layers:
224
+ - Each agent receives its task ID and metadata context in the prompt
225
+ - Agent must call TaskUpdate(status: "in_progress") before starting
226
+ - Agent must call TaskUpdate(status: "completed", metadata: { files_created: [...] }) when done
227
+ - Agent principal monitors via TaskList() after all agents complete
228
+ - Agent principal updates activeForm after each entity completion:
229
+ `TaskUpdate(taskId: layer3_task_id, activeForm: "Building {EntityName} frontend (2/5 entities)")`
230
+
231
+ ### Frontend Compliance Gate
232
+
233
+ > See `references/smartstack-frontend-compliance.md` section 9 "Compliance Gates" for all 6 required checks:
234
+ > 1. CSS Variables (theme system)
235
+ > 2. Forms as Pages (zero modals/drawers/slide-overs)
236
+ > 3. I18n File Structure (4 languages, separate JSON files)
237
+ > 4. Lazy Loading (React.lazy() — no static imports)
238
+ > 5. useTranslation in Pages (all text translated)
239
+ > 6. SmartStack Components (no raw HTML tables — DataTable/EntityCard required)
240
+
241
+ Do not commit frontend changes until all 6 gates pass.
242
+
243
+ When delegating to `/ui-components` skill, include explicit instructions:
244
+ - "CSS: Use CSS variables ONLY — `bg-[var(--bg-card)]`, `text-[var(--text-primary)]`."
245
+ - "Forms: Create/Edit forms are FULL PAGES with own routes (e.g., `/create`, `/:id/edit`)."
246
+ - "I18n: ALL text must use `t('namespace:key', 'Fallback')`. Generate JSON files in `src/i18n/locales/`."
247
+
248
+ ### Frontend Tests Inline
249
+
250
+ > **Tests are scaffolded and run WITHIN Layer 3, not deferred to step-07.**
251
+
252
+ ```
253
+ 1. Scaffold frontend tests:
254
+ → For each module with create/edit pages:
255
+ → Generate EntityCreatePage.test.tsx and EntityEditPage.test.tsx
256
+ → Co-located next to the page component (NOT in __tests__/ folder)
257
+ → Cover: rendering, validation, submit, pre-fill, navigation, errors
258
+ → Tools: Vitest + React Testing Library + @testing-library/user-event
259
+ → Mock API: vi.mock() or MSW — NEVER real API calls
260
+
261
+ 2. Run tests:
262
+ WEB_DIR=$(find . -name "vitest.config.ts" -not -path "*/node_modules/*" -exec dirname {} \; 2>/dev/null | head -1)
263
+ if [ -n "$WEB_DIR" ]; then
264
+ (cd "$WEB_DIR" && npm run test)
265
+ fi
266
+
267
+ 3. Fix loop (max 3 iterations):
268
+ IF tests fail:
269
+ → Identify root cause (ALWAYS code bug, not test bug)
270
+ → Fix production CODE
271
+ → Re-run tests
272
+ → Repeat until pass or max 3
273
+
274
+ 4. If still failing after 3 iterations: note failures, continue.
275
+ Step-07 "Final Test Sweep" will handle remaining failures.
276
+ ```
277
+
278
+ ### Typecheck Gate
279
+
280
+ ```bash
281
+ npm run typecheck
282
+ ```
283
+
284
+ Must pass before commit.
285
+
286
+ TaskUpdate(taskId: layer3_task_id, status: "completed",
287
+ metadata: { build_gate: "pass" })
288
+
289
+ ### Layer 3 Commits
290
+
291
+ ```
292
+ feat({module}): [frontend] pages, routes, i18n, documentation
293
+ test({module}): frontend form tests
294
+ ```
295
+
296
+ ---
297
+
298
+ ## NEXT SUB-STEP
299
+
300
+ Load `steps/step-03e-layer4-devdata.md`
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: step-03e-layer4-devdata
3
+ description: "Layer 4: Development test data (optional)"
4
+ model: opus
5
+ parent_step: steps/step-03-execute.md
6
+ ---
7
+
8
+ ## Layer 4 — DevData (optional)
9
+
10
+ ### Task Progress
11
+ IF layer4 task exists: TaskUpdate(taskId: layer4_task_id, status: "in_progress")
12
+ IF layer4 task exists: TaskUpdate(taskId: progress_tracker_id,
13
+ description: "Module: {module_code}. Current: step-03 (Execute), Layer 4",
14
+ activeForm: "Executing Layer 4")
15
+
16
+ > **Business test data for development/demo environments.**
17
+ > Skip this layer if no meaningful test data is needed.
18
+
19
+ ```
20
+ 1. Create DevDataSeeder:
21
+ → Infrastructure/Persistence/Seeding/DevData/{Module}DevDataSeeder.cs
22
+ → ALL entities MUST include TenantId
23
+ → Realistic business data for demo purposes
24
+
25
+ 2. Build gate:
26
+ dotnet build → MUST PASS
27
+ ```
28
+
29
+ <!-- TODO A13: Replace with MCP scaffold_extension(type: "devdata") when B5 is ready -->
30
+
31
+ IF layer4 task exists: TaskUpdate(taskId: layer4_task_id, status: "completed",
32
+ metadata: { build_gate: "pass" })
33
+
34
+ ### Layer 4 Commit (if applicable)
35
+
36
+ ```
37
+ feat({module}): [devdata] test data for development
38
+ ```
39
+
40
+ ---
41
+
42
+ ## SUB-STEPS COMPLETE
43
+
44
+ Return to `steps/step-03-execute.md` for PRD State Update, State Auto-Save, and routing to step-04.
@@ -16,15 +16,8 @@ next_step: steps/step-05-deep-review.md
16
16
 
17
17
  ## 0. Task Progress
18
18
 
19
- ### Progress Tracker Update
20
- ```
21
- TaskUpdate(taskId: progress_tracker_id,
22
- description: "Module: {module_code}. Current: step-04 (eXamine)",
23
- activeForm: "Validating conventions")
24
- ```
25
-
26
- ### eXamine Task Lifecycle
27
19
  ```
20
+ TaskUpdate(taskId: progress_tracker_id, description: "Module: {module_code}. Current: step-04 (eXamine)", activeForm: "Validating conventions")
28
21
  TaskUpdate(taskId: examine_task_id, status: "in_progress")
29
22
  ```
30
23
 
@@ -34,64 +27,41 @@ TaskUpdate(taskId: examine_task_id, status: "in_progress")
34
27
 
35
28
  ```
36
29
  Call: mcp__smartstack__validate_conventions
37
-
38
- Expected: 0 errors
39
- If errors found:
40
- → Fix each error (use appropriate skill/MCP)
41
- → Re-validate until 0 errors
30
+ Expected: 0 errors. Fix and re-validate if any found.
42
31
  ```
43
32
 
44
- ---
45
-
46
33
  ## 2. EF Core Migration Check (if needs_migration)
47
34
 
48
35
  ```
49
36
  Call: mcp__smartstack__check_migrations
50
-
51
- Verify:
52
- - Migration exists and is applied
53
- - No pending model changes
54
- - ModelSnapshot matches
37
+ Verify: Migration exists, no pending changes, ModelSnapshot matches.
55
38
  ```
56
39
 
57
- ---
58
-
59
40
  ## 3. Frontend Route Validation (if frontend modified)
60
41
 
61
42
  ```
62
43
  Call: mcp__smartstack__validate_frontend_routes
63
44
 
64
45
  Verify:
65
- - Routes nested inside correct Layout wrapper
66
- - Route paths match controller patterns
46
+ - Routes nested in correct Layout wrapper
47
+ - Route paths match controller patterns, include module segment
67
48
  - No orphan routes
68
- - Route paths include module segment (e.g., 'employee-management/employees', NOT just 'employees')
69
- → Compare frontend route paths in App.tsx against backend NavigationSeedData routes
70
- → If backend defines route /app/module/section, frontend must use module/section (relative)
49
+ - Compare frontend routes (componentRegistry.generated.ts or App.tsx) against backend NavigationSeedData routes
71
50
  ```
72
51
 
73
- ### 3b. Frontend Page Completeness
74
-
75
- > POST-CHECKs C4, C5, and C6 in `references/post-checks.md` cover this verification (dead navigation links, missing Create/Edit pages, missing test files). Executed in section 6b below.
76
- >
77
- > ROOT CAUSE (test-v4-015): Frontend generation created List + Detail pages but SKIPPED Create + Edit pages → white screen / 404.
78
-
79
- **If ANY check fails → return to step-03 to generate the missing pages, tests, or routes.**
52
+ > **Page completeness:** POST-CHECKs C4, C5, C6 (dead links, missing Create/Edit, missing tests) executed in section 6b.
53
+ > **If ANY check fails → return to step-03.**
80
54
 
81
55
  ---
82
56
 
83
57
  ## 4. Build Verification
84
58
 
85
59
  ```bash
86
- # Backend
87
60
  dotnet clean && dotnet restore && dotnet build
88
- # Note: WSL bin\Debug cleanup handled by PostToolUse hook (wsl-dotnet-cleanup.sh)
89
-
90
- # Frontend (if applicable)
91
- npm run typecheck
61
+ npm run typecheck # if applicable
92
62
  ```
93
63
 
94
- Both must pass. If failure, classify error per `references/error-classification.md` (categories A-F).
64
+ Both must pass. Classify errors per `references/error-classification.md` (A-F).
95
65
 
96
66
  ---
97
67
 
@@ -101,30 +71,22 @@ Both must pass. If failure, classify error per `references/error-classification.
101
71
  INFRA_PROJECT=$(ls src/*Infrastructure*/*.csproj 2>/dev/null | head -1)
102
72
  API_PROJECT=$(ls src/*Api*/*.csproj 2>/dev/null | head -1)
103
73
 
104
- # Pending model changes check (BLOCKING if pending)
105
- dotnet ef migrations has-pending-model-changes \
106
- --project "$INFRA_PROJECT" \
107
- --startup-project "$API_PROJECT"
74
+ # Check pending model changes
75
+ dotnet ef migrations has-pending-model-changes --project "$INFRA_PROJECT" --startup-project "$API_PROJECT"
108
76
 
109
- # Migration application test (SQL Server LocalDB)
77
+ # Apply to SQL Server LocalDB
110
78
  DB_NAME="SmartStack_Apex_Examine_$(date +%s)"
111
- CONN_STRING="Server=(localdb)\\MSSQLLocalDB;Database=$DB_NAME;Integrated Security=true;TrustServerCertificate=true;Connect Timeout=120;"
112
- dotnet ef database update \
113
- --connection "$CONN_STRING" \
114
- --project "$INFRA_PROJECT" \
115
- --startup-project "$API_PROJECT"
79
+ dotnet ef database update --connection "Server=(localdb)\\MSSQLLocalDB;Database=$DB_NAME;Integrated Security=true;TrustServerCertificate=true;Connect Timeout=120;" --project "$INFRA_PROJECT" --startup-project "$API_PROJECT"
116
80
 
117
- # Integration tests on real SQL Server (if project exists)
81
+ # Run integration tests if present
118
82
  INT_TEST_PROJECT=$(ls tests/*Tests.Integration*/*.csproj 2>/dev/null | head -1)
119
- if [ -n "$INT_TEST_PROJECT" ]; then
120
- dotnet test "$INT_TEST_PROJECT" --no-build --verbosity normal
121
- fi
83
+ [ -n "$INT_TEST_PROJECT" ] && dotnet test "$INT_TEST_PROJECT" --no-build --verbosity normal
122
84
 
123
85
  # Cleanup
124
86
  sqlcmd -S "(localdb)\MSSQLLocalDB" -Q "IF DB_ID('$DB_NAME') IS NOT NULL BEGIN ALTER DATABASE [$DB_NAME] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; DROP DATABASE [$DB_NAME]; END" 2>/dev/null
125
87
  ```
126
88
 
127
- If migration fails on SQL Server (common: SQLite-only syntax, column type mismatches, missing FK targets), fix the DbContext or migration first.
89
+ If migration fails (SQLite-only syntax, type mismatches, missing FK targets), fix the DbContext or migration first.
128
90
 
129
91
  ---
130
92
 
@@ -132,137 +94,95 @@ If migration fails on SQL Server (common: SQLite-only syntax, column type mismat
132
94
 
133
95
  | File | Checks |
134
96
  |------|--------|
135
- | NavigationApplicationSeedData | MUST be first, 4 lang translations |
136
- | ApplicationRolesSeedData | 4 roles (admin, manager, contributor, viewer), references NavigationApplicationSeedData.ApplicationId |
137
- | NavigationModuleSeedData | 4 languages (fr, en, it, de), GetModuleEntry + GetTranslationEntries |
138
- | ↳ Section methods (same file) | (conditional: if sections exist) GetSectionEntries + GetSectionTranslationEntries, 4 languages, random GUIDs, query actual module from DB for FK |
139
- | ↳ Resource methods (same file) | (conditional: if resources exist) GetResourceEntries + resource translations, 4 languages, random GUIDs, query actual section from DB for FK |
140
- | Permissions.cs | Static constants class with `public static class {Module} { Read, Create, Update, Delete }`, paths match PermissionsSeedData |
141
- | PermissionsSeedData | MCP generate_permissions used, paths match Permissions.cs, wildcard + CRUD |
142
- | RolesSeedData | Admin=wildcard(*), Manager=CRU, Contributor=CR, Viewer=R. Role-permission entries reference permission paths from PermissionsSeedData |
143
- | IClientSeedDataProvider | 4 Seed methods (Navigation, Roles, Permissions, RolePermissions), idempotent, factory methods, SaveChanges per group |
97
+ | NavigationApplicationSeedData | 4 lang translations |
98
+ | ApplicationRolesSeedData | 4 roles, references NavigationApplicationSeedData.ApplicationId |
99
+ | NavigationModuleSeedData | 4 languages, GetModuleEntry + translations |
100
+ | ↳ Section methods | GetSectionEntries + translations, 4 languages, random GUIDs |
101
+ | ↳ Resource methods | GetResourceEntries + translations, 4 languages, random GUIDs |
102
+ | Permissions.cs | Static class with Read/Create/Update/Delete constants, match PermissionsSeedData |
103
+ | PermissionsSeedData | MCP generate_permissions, paths match Permissions.cs |
104
+ | RolesSeedData | Admin=wildcard(*), Manager=CRU, Contributor=CR, Viewer=R |
105
+ | IClientSeedDataProvider | 4 Seed methods, idempotent, SaveChanges per group |
144
106
  | DI Registration | `services.AddScoped<IClientSeedDataProvider, {App}SeedDataProvider>()` |
145
107
 
146
108
  ---
147
109
 
148
110
  ## 6b. POST-CHECKs
149
111
 
150
- > **MCP FIRST:** Run `validate_conventions`, `validate_security`, and `validate_frontend_routes` before bash checks.
151
- > These 3 MCP tools cover ~10 additional checks automatically.
152
-
153
- Load and execute all checks from `references/post-checks.md` (security + convention + architecture checks).
112
+ **MCP FIRST:** Run `validate_conventions`, `validate_security`, `validate_frontend_routes` (covers ~10 checks).
154
113
 
155
- If any POST-CHECK fails, fix in step-03 and re-validate.
114
+ Execute all checks from `references/post-checks.md`. If any fails, fix in step-03 and re-validate.
156
115
 
157
116
  ---
158
117
 
159
118
  ## 7. Acceptance Criteria POST-CHECK
160
119
 
161
- For each AC inferred in step-01:
162
-
120
+ For each AC from step-01:
163
121
  ```
164
- AC1: {criterion} → PASS / FAIL (evidence: {file:line or test})
165
- AC2: {criterion} → PASS / FAIL (evidence: {file:line or test})
122
+ AC1: {criterion} → PASS / FAIL (evidence)
166
123
  ...
167
124
  ```
168
-
169
- **All ACs must PASS. If any FAIL, go back to step-03 to fix.**
125
+ **All ACs must PASS. If any FAIL, return to step-03.**
170
126
 
171
127
  ---
172
128
 
173
129
  ## 8. eXamine Summary
174
130
 
175
- ```
176
131
  **APEX SmartStack - eXamine Complete**
177
132
 
178
- | Layer | Status | Details |
179
- |-------|--------|---------|
180
- | Layer 0 — Domain + Infrastructure | PASS / N/A | Entities, EF configs, migration, build gate |
181
- | Layer 1 — Seed Data | PASS / N/A | Navigation, permissions, roles, provider, build gate |
182
- | Layer 2 — Backend | PASS / N/A | Services, controllers, build gate, inline tests |
183
- | Layer 3 — Frontend | PASS / N/A | Pages, i18n, docs, compliance gate, inline tests |
184
- | Layer 4 — DevData | PASS / N/A / SKIPPED | Optional test data |
185
-
186
- | Category | Checks | Status |
187
- |----------|--------|--------|
188
- | MCP conventions | validate_conventions | PASS (0 errors) |
189
- | Build | dotnet build + npm typecheck | PASS |
190
- | EF Core | migrations, pending changes, SQL Server apply | PASS / N/A |
191
- | DB tests | Integration tests on SQL Server | PASS / N/A |
192
- | Frontend | routes, lazy loading, forms as pages, i18n (4 langs + keys) | PASS / N/A |
193
- | Security | TenantId filter, RequirePermission, no Guid.Empty, no !.Value | PASS / N/A |
194
- | Seed data | completeness, random GUIDs (Guid.NewGuid()), no ContextId/RoleId constants | PASS / N/A |
195
- | Code quality | PaginatedResult, EntityLookup (no FK select/input), CSS vars, search param | PASS / N/A |
196
- | Migration completeness | ModelSnapshot covers ALL DbSet entities (POST-CHECK C38, C42) | PASS / N/A |
197
- | NavRoute kebab-case | NavRoute + permissions use kebab-case (POST-CHECK C34) | PASS / N/A |
198
- | DateOnly DTOs | Date fields use DateOnly not string (POST-CHECK C41) | PASS / N/A |
199
- | I18n registration | Namespaces registered in i18n config (POST-CHECK C39) | PASS / N/A |
200
- | Validators DI | FluentValidation registered in DI (POST-CHECK C40) | PASS / N/A |
201
- | Route/NavRoute conflict | No [Route] alongside [NavRoute] on controllers (POST-CHECK C43) | PASS / N/A |
202
- | Route module segment | Frontend routes include module segment matching seed data (POST-CHECK C52) | PASS / N/A |
203
- | Role-permission matrix | Admin=wildcard, Manager=CRU, Contributor=CR, Viewer=R (POST-CHECK C44) | PASS / N/A |
204
- | PermissionAction enum | No Enum.Parse, only typed enum values 0-10 (POST-CHECK C45) | PASS / N/A |
205
- | Navigation translations | 4 langs per level, section/resource translations present (POST-CHECK C46) | PASS / N/A |
206
- | Inline tests (Layer 2) | Backend unit + integration tests | PASS / N/A |
207
- | Inline tests (Layer 3) | Frontend form tests | PASS / N/A |
208
- | POST-CHECKs | 3 MCP tools + bash checks (security + convention + architecture) | PASS / N/A |
209
- | Acceptance criteria | AC1..ACn | {X}/{Y} PASS |
210
- ```
133
+ | Layer | Status |
134
+ |-------|--------|
135
+ | Layer 0 — Domain + Infrastructure | PASS / N/A |
136
+ | Layer 1 — Seed Data | PASS / N/A |
137
+ | Layer 2 — Backend | PASS / N/A |
138
+ | Layer 3 — Frontend | PASS / N/A |
139
+ | Layer 4 — DevData | PASS / N/A / SKIPPED |
140
+
141
+ | Category | Status |
142
+ |----------|--------|
143
+ | MCP conventions | PASS (0 errors) |
144
+ | Build (dotnet + npm) | PASS |
145
+ | EF Core (migrations, SQL Server) | PASS / N/A |
146
+ | Integration tests | PASS / N/A |
147
+ | Frontend routes + i18n | PASS / N/A |
148
+ | Security checks | PASS / N/A |
149
+ | Seed data completeness | PASS / N/A |
150
+ | Code quality | PASS / N/A |
151
+ | NavRoute kebab-case | PASS / N/A |
152
+ | DateOnly DTOs | PASS / N/A |
153
+ | I18n registration | PASS / N/A |
154
+ | FluentValidation DI | PASS / N/A |
155
+ | Route/NavRoute conflict | PASS / N/A |
156
+ | Role-permission matrix | PASS / N/A |
157
+ | Navigation translations (4 langs) | PASS / N/A |
158
+ | Inline tests | PASS / N/A |
159
+ | POST-CHECKs | PASS / N/A |
160
+ | Acceptance criteria | {X}/{Y} PASS |
211
161
 
212
162
  ---
213
163
 
214
- ## 9. Save Output (if save_mode)
164
+ ## 8b. Runtime Validation
215
165
 
216
- Write to `{output_dir}/04-examine.md` with validation results.
166
+ For runtime validation (if NOT foundation/economy mode): Run `/validate-feature {EntityName}` (OPTIONAL but RECOMMENDED).
217
167
 
218
168
  ---
219
169
 
220
- ## 10. Route to Next Step — FINAL TEST SWEEP
221
-
222
- > **Note:** Backend tests (Layer 2) and frontend tests (Layer 3) have already been scaffolded and run inline.
223
- > Step-07 "Final Test Sweep" handles: security tests, coverage analysis, cross-layer scenarios, and remaining failures.
170
+ ## 9. Route to Next Step
224
171
 
225
172
  ```
226
- IF examine_mode (-x flag):
227
- Load steps/step-05-deep-review.md (adversarial review)
228
- → Then step-06 (resolve) if findings need fixing
229
- → Then step-07 (Final Test Sweep) — ALWAYS
173
+ IF examine_mode: Load step-05 → step-06 → step-07
174
+ ELSE: Load step-07-tests.md
230
175
 
231
- ELSE:
232
- → Load steps/step-07-tests.md — IMMEDIATELY after eXamine completes
233
- ```
234
-
235
- **RULE:** The APEX workflow is NOT complete until steps 07-08 execute.
236
- The success criteria require: "Tests: 100% pass, >= 80% coverage" — step-07 verifies coverage and adds security tests.
237
-
238
- ### eXamine Task Lifecycle — Completion
239
- ```
240
176
  TaskUpdate(taskId: examine_task_id, status: "completed")
241
177
  ```
242
178
 
243
- **NEXT ACTION:** Load `steps/step-07-tests.md` now.
179
+ **RULE:** APEX requires steps 07-08 (100% tests, >= 80% coverage).
244
180
 
245
- ---
246
-
247
- ## 11. PRD Final Reconciliation (delegate mode only)
248
-
249
- > **After all validation passes**, ensure the PRD file reflects the completed state.
181
+ ## 10. PRD Reconciliation (delegate mode)
250
182
 
251
183
  ```
252
- IF delegate_mode:
253
- Read {delegate_prd_path}
254
-
255
- For ALL tasks belonging to this module:
256
- IF task was executed by apex AND all checks passed:
257
- Verify task.status == 'completed'
258
- IF task was NOT in scope (different module):
259
- Leave unchanged
260
-
261
- Set prd.updated_at = new Date().toISOString()
262
-
263
- If ALL module tasks completed:
264
- Set prd.status = 'completed' (if single module)
265
- OR leave prd.status = 'in_progress' (if multi-module, other modules remain)
266
-
267
- Write back to {delegate_prd_path}
184
+ For all tasks in module:
185
+ IF executed AND checks passed: Set task.status = 'completed'
186
+ Set prd.updated_at = now
187
+ If all done: Set prd.status = 'completed' (single) or 'in_progress' (multi)
268
188
  ```