@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
@@ -1,162 +1,70 @@
1
- # Frontend: Route Wiring in App.tsx
1
+ # Frontend: Route Registration with PageRegistry + DynamicRouter
2
2
 
3
- > Referenced from `steps/step-03-execute.md`Detailed route wiring patterns and verification.
3
+ > **v3.7+**Replaces the legacy Pattern A (mergeRoutes) and Pattern B (JSX routes) patterns.
4
4
 
5
5
  ---
6
6
 
7
- ## Step 4: Wire Routes to App.tsx
7
+ ## How It Works
8
8
 
9
- **Important:** This step is required. Without it, routes exist as files but are invisible to the React Router. The page will be blank.
9
+ 1. **Backend seed data** defines navigation entries with `ComponentKey` values
10
+ (e.g., `administration.users`, `support.tickets.list`)
11
+ 2. **`componentRegistry.generated.ts`** registers all page components into `PageRegistry`
12
+ via `PageRegistry.register('key', lazy(() => import(...)))`
13
+ 3. **DynamicRouter** fetches the menu API, matches each entry's `componentKey` to a
14
+ `PageRegistry` entry, and generates `<Route>` elements at runtime
15
+ 4. **Implicit routes** (detail, create, edit) are resolved by convention:
16
+ - `*.detail` → `.../:id`
17
+ - `*.create` → `.../create`
18
+ - `*.edit` → `.../:id/edit`
10
19
 
11
- After `scaffold_routes` generates the route files, you MUST manually insert the routes into `App.tsx`.
20
+ No manual App.tsx wiring is needed.
12
21
 
13
22
  ---
14
23
 
15
- ## Step 4a: Import Page Components (Lazy Loading ONLY)
24
+ ## For SmartStack Core Pages
16
25
 
17
- At the top of App.tsx, ALL page imports MUST use `React.lazy()`:
26
+ `componentRegistry.generated.ts` is auto-generated by MCP `scaffold_routes`:
18
27
 
19
28
  ```tsx
20
- // CORRECTLazy loading (MANDATORY per POST-CHECK S6)
21
- const {EntityName}Page = lazy(() =>
22
- import('@/pages/{Application}/{Module}/{EntityName}Page')
23
- .then(m => ({ default: m.{EntityName}Page }))
24
- );
25
-
26
- // WRONG — Static import is BLOCKING per POST-CHECK S6
27
- // import { {EntityName}Page } from '@/pages/{Application}/{Module}/{EntityName}Page';
29
+ // Auto-generatedDO NOT EDIT
30
+ import { lazy } from 'react';
31
+ import { PageRegistry } from '@/extensions/PageRegistry';
32
+
33
+ PageRegistry.register('administration.users', lazy(() =>
34
+ import('@/pages/platform/administration/users/UsersPage').then(m => ({ default: m.UsersPage }))
35
+ ));
36
+ PageRegistry.register('administration.users.detail', lazy(() =>
37
+ import('@/pages/platform/administration/users/UserDetailPage').then(m => ({ default: m.UserDetailPage }))
38
+ ));
39
+ // ... ~100 registrations
28
40
  ```
29
41
 
30
- ---
31
-
32
- ## Step 4a.5: Import Generated Route Extensions (if scaffold_routes was used)
33
-
34
- If `scaffold_routes` generated `applicationRoutes.generated.tsx`, import and spread:
35
-
42
+ Imported once in `main.tsx`:
36
43
  ```tsx
37
- import { applicationRouteExtensions } from '@/routes/applicationRoutes.generated';
38
-
39
- const applicationRoutes: ApplicationRouteExtensions = {
40
- ...applicationRouteExtensions,
41
- // additional manual routes if needed...
42
- };
44
+ import './extensions/componentRegistry.generated';
43
45
  ```
44
46
 
45
- If no generated file exists, add routes directly to the existing `applicationRoutes` object.
46
-
47
47
  ---
48
48
 
49
- ## Step 4b: Detect App.tsx Routing Pattern
50
-
51
- Read App.tsx and detect which pattern is used:
49
+ ## For Client SDK Pages
52
50
 
53
- ### Pattern A: applicationRoutes Object
54
-
55
- **If App.tsx contains:** `applicationRoutes: ApplicationRouteExtensions`
56
-
57
- → Add routes to `applicationRoutes.{application}[]` with **RELATIVE** paths (no leading `/`)
58
-
59
- > **CRITICAL — Include Module Segment:** Paths are relative to `/{application}/`.
60
- > For a 3-level hierarchy (app → module → sections), paths MUST be `{module_kebab}/{section_kebab}`.
61
- > Using just `{section_kebab}` omits the module segment → route resolves to `/{app}/{section}` instead
62
- > of `/{app}/{module}/{section}` → mismatch with backend navigation seed data → 404.
51
+ Clients register their own pages directly:
63
52
 
64
53
  ```tsx
65
- const applicationRoutes: ApplicationRouteExtensions = {
66
- 'human-resources': [
67
- // existing routes...
68
- // Paths include module segment: employee-management/employees (NOT just employees)
69
- { path: '{module_kebab}/{section_kebab}', element: <{EntityName}ListPage /> },
70
- { path: '{module_kebab}/{section_kebab}/create', element: <Create{EntityName}Page /> },
71
- { path: '{module_kebab}/{section_kebab}/:id', element: <{EntityName}DetailPage /> },
72
- { path: '{module_kebab}/{section_kebab}/:id/edit', element: <Edit{EntityName}Page /> },
73
-
74
- // Parent redirect routes (MANDATORY — prevents /login redirect on parent navigation)
75
- { path: '{module_kebab}', element: <Navigate to="{module_kebab}/{first_section_kebab}" replace /> },
76
- { path: '', element: <Navigate to="{first_module_kebab}/{first_section_kebab}" replace /> },
77
- ],
78
- };
79
-
80
- // Concrete example: app=human-resources, module=employee-management, sections=employees,absences
81
- const applicationRoutes: ApplicationRouteExtensions = {
82
- 'human-resources': [
83
- { path: 'employee-management/employees', element: <EmployeesPage /> }, // ✅
84
- { path: 'employee-management/employees/create', element: <CreateEmployeePage /> }, // ✅
85
- { path: 'employee-management/employees/:id', element: <EmployeeDetailPage /> }, // ✅
86
- // ...absences...
87
- { path: 'employee-management', element: <Navigate to="employee-management/employees" replace /> },
88
- { path: '', element: <Navigate to="employee-management/employees" replace /> },
89
- ],
90
- };
91
-
92
- // ❌ WRONG — missing module segment:
93
- // { path: 'employees', ... } → resolves to /human-resources/employees (backend expects /human-resources/employee-management/employees)
94
- ```
95
- ```
96
-
97
- Routes are automatically injected into BOTH standard (`/{application}/...`) and tenant-prefixed (`/t/:slug/{application}/...`) route trees by `mergeRoutes()`. No manual duplication needed.
98
-
99
- #### Custom Applications (Pattern A)
54
+ import { PageRegistry } from '@atlashub/smartstack';
55
+ import { lazy } from 'react';
100
56
 
101
- Custom application keys (any key **not** in the built-in list: `administration`, `support`, `user`, `api`) are fully supported in `applicationRoutes`. `mergeRoutes()` automatically:
102
-
103
- 1. Creates a new route entry wrapped in `<AppLayout />`
104
- 2. Injects it into **both** standard (`/{app-key}/...`) and tenant-prefixed (`/t/:slug/{app-key}/...`) trees, inside `TenantRouteWrapper > RouteGuard > LicenseGuard`
105
- 3. Generates automatic parent redirect routes (e.g., `employees` → `employees/management`)
106
-
107
- No need to use Pattern B for custom applications — Pattern A handles everything automatically.
108
-
109
- ### Pattern B: JSX Routes
110
-
111
- **If App.tsx contains:** `<Route path="/{application}" element={<{Layout} />}>`
112
-
113
- → Insert `<Route>` children inside the Layout wrapper:
114
-
115
- ```tsx
116
- <Route path="/human-resources" element={<AppLayout />}>
117
- {/* ... existing routes ... */}
118
- <Route path="{module_kebab}" element={<{EntityName}Page />} />
119
- </Route>
57
+ PageRegistry.register('rh.time.dashboard', lazy(() => import('./pages/TimeDashboard')));
58
+ PageRegistry.register('rh.time.list', lazy(() => import('./pages/TimeList')));
59
+ PageRegistry.register('rh.time.detail', lazy(() => import('./pages/TimeDetail')));
120
60
  ```
121
61
 
122
- **ALSO add the same routes inside the tenant-prefixed block:**
123
-
124
- Find `<Route path="/t/:slug">` and add the **same route entries** there.
62
+ Navigation entries are created in DB (via admin UI or seed data).
63
+ DynamicRouter does the junction automatically.
125
64
 
126
65
  ---
127
66
 
128
- ## Step 4b.5: Verify mergeRoutes() Call
129
-
130
- **Before modifying routes, READ App.tsx and verify the `mergeRoutes()` call has 2 parameters.**
131
-
132
- ✅ Correct:
133
- ```tsx
134
- const routes = mergeRoutes(clientRoutes, applicationRoutes);
135
- ```
136
-
137
- ❌ If you see only 1 parameter:
138
- ```tsx
139
- const routes = mergeRoutes(clientRoutes);
140
- ```
141
-
142
- → Add the `applicationRoutes` object and pass it as 2nd parameter.
143
- Without it, all application routes are silently ignored → blank page or /login redirect.
144
-
145
- **Do not remove the `applicationRoutes` parameter or the `ApplicationRouteExtensions` import.**
146
-
147
- ---
148
-
149
- ## Step 4c: Application-to-Layout Mapping
150
-
151
- | Application prefix | Layout Component | Route path |
152
- |---------|------------------|------------|
153
- | `administration.*` | `AppLayout` | `/administration` |
154
- | `*` (business apps) | `AppLayout` | `/{application}` |
155
- | `myspace.*` | `AppLayout` | `/myspace` |
156
-
157
- ---
158
-
159
- ## Step 4d: Verify Wiring
67
+ ## Verification
160
68
 
161
69
  ```
162
70
  Tool: mcp__smartstack__validate_frontend_routes
@@ -164,68 +72,17 @@ Args:
164
72
  scope: "routes"
165
73
  ```
166
74
 
167
- If `appWiring.issues` is not empty, fix the wiring before proceeding.
168
-
169
- ---
170
-
171
- ## Step 4e: Parent Redirect Routes
172
-
173
- **Important:** Without parent redirects, navigating to an application or module URL (e.g., `/human-resources` or `/human-resources/employees`) will cause a redirect to `/login` because no route matches.
174
-
175
- For each application, add:
176
-
177
- 1. **Application root redirect** — redirects `/{application}` to the first module/section:
178
- ```tsx
179
- { path: '', element: <Navigate to="{first_module}/{first_section}" replace /> }
180
- ```
181
-
182
- 2. **Module redirect** (if modules have sections) — redirects `/{application}/{module}` to first section:
183
- ```tsx
184
- { path: '{module}', element: <Navigate to="{module}/{first_section}" replace /> }
185
- ```
186
-
187
- **Example:** For NavRoutes `human-resources.employee-management.employees` and `human-resources.employee-management.absences`:
188
- ```tsx
189
- { path: 'employee-management', element: <Navigate to="employee-management/employees" replace /> },
190
- { path: '', element: <Navigate to="employee-management/employees" replace /> },
191
- ```
192
-
193
- The `to` prop is resolved relative to the **parent route** (`/{application}`), so always use the full path from the application root.
194
-
195
- > Note: `scaffold_routes` with `outputFormat: "applicationRoutes"` generates these redirects automatically.
196
-
197
- ---
198
-
199
- ## Patterns to Avoid (BOTH patterns)
200
-
201
- - Do not add application routes to `clientRoutes[]` with absolute paths — `clientRoutes` is only for routes outside SmartStack applications (e.g., `/about`, `/pricing`)
202
- - Do not add routes outside the Layout wrapper (shell will not render)
203
- - Do not use `createBrowserRouter` (SmartStack uses `useRoutes()` + `mergeRoutes()`)
204
- - Do not add custom application routes to `clientRoutes[]` with absolute paths:
205
- ```tsx
206
- // ❌ WRONG — bypasses RouteGuard + TenantLayout + AppLayout → /login redirect
207
- const clientRoutes: RouteConfig[] = [
208
- { path: '/human-resources/employees/management', element: <EmployeePage /> },
209
- ];
210
- ```
211
- Custom application routes go in `applicationRoutes` with RELATIVE paths (including module segment):
212
- ```tsx
213
- // ✅ CORRECT — module segment included
214
- const applicationRoutes: ApplicationRouteExtensions = {
215
- 'human-resources': [
216
- { path: 'employee-management/employees', element: <EmployeesPage /> },
217
- ],
218
- };
219
- ```
220
- - Do not remove the `applicationRoutes` 2nd parameter from `mergeRoutes()` — this silently breaks all custom routes
75
+ Checks:
76
+ - `componentRegistry.generated.ts` exists
77
+ - Each backend NavRoute has a `PageRegistry.register()` call
78
+ - `main.tsx` imports the generated file
79
+ - Implicit route keys (*.detail, *.create, *.edit) exist for CRUD pages
221
80
 
222
81
  ---
223
82
 
224
- ## Verification Checklist
83
+ ## Legacy Patterns (DEPRECATED)
225
84
 
226
- - [ ] Routes are inside the AppLayout wrapper
227
- - [ ] Routes use NESTED structure (not flat)
228
- - [ ] Application kebab-case matches navigation seed data
229
- - [ ] Both standard and tenant-prefixed blocks have routes (if using Pattern B)
230
- - [ ] Page components are imported at top of App.tsx
231
- - [ ] `mcp__smartstack__validate_frontend_routes` returns no issues
85
+ > The Pattern A (`mergeRoutes(clientRoutes, applicationRoutes)`) and Pattern B
86
+ > (JSX `<Route>` in App.tsx) patterns are deprecated since v3.7.
87
+ > They still work but are not recommended for new development.
88
+ > See git history for the legacy documentation.