@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
@@ -48,8 +48,8 @@ Display generated frontend code organized by category:
48
48
 
49
49
  ### Routes
50
50
  - Updated `navRoutes.generated.ts`
51
- - Generated `applicationRoutes.generated.tsx`
52
- - Wired routes in `App.tsx` (standard + tenant blocks)
51
+ - Generated `componentRegistry.generated.ts` (PageRegistry registrations)
52
+ - Navigation seed data has matching componentKeys
53
53
 
54
54
  ### i18n
55
55
  - `locales/fr/{entityCode}.json`
@@ -50,8 +50,12 @@ Navigation seed data:
50
50
  Route = "/human-resources/time-management" // From ToKebabCase()
51
51
  ```
52
52
 
53
- App.tsx routes must use:
53
+ PageRegistry keys and seed data ComponentKeys must use kebab-case:
54
54
  ```tsx
55
+ // v3.7+ (DynamicRouter): componentKey uses dot-separated kebab-case
56
+ PageRegistry.register('human-resources.time-management', lazy(() => ...));
57
+
58
+ // Legacy (applicationRoutes): paths use kebab-case
55
59
  const applicationRoutes: ApplicationRouteExtensions = {
56
60
  'human-resources': [ // ← kebab-case
57
61
  { path: 'time-management', element: <TimeManagementPage /> }, // ← kebab-case
@@ -1,168 +1,70 @@
1
- # Frontend: Route Wiring in App.tsx
1
+ # Frontend: Route Registration with PageRegistry + DynamicRouter
2
2
 
3
- > Referenced from `steps/step-05-frontend.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 (BLOCKING)
7
+ ## How It Works
8
8
 
9
- **CRITICAL:** This step is MANDATORY. 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
24
+ ## For SmartStack Core Pages
16
25
 
17
- At the top of App.tsx:
26
+ `componentRegistry.generated.ts` is auto-generated by MCP `scaffold_routes`:
18
27
 
19
28
  ```tsx
20
- import { {EntityName}Page } from '@/pages/{Application}/{Module}/{EntityName}Page';
21
- // Or lazy-loaded:
22
- const {EntityName}Page = lazy(() => import('@/pages/{Application}/{Module}/{EntityName}Page'));
29
+ // Auto-generated DO 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
23
40
  ```
24
41
 
25
- ---
26
-
27
- ## Step 4a.5: Import Generated Route Extensions (if scaffold_routes was used)
28
-
29
- If `scaffold_routes` generated `applicationRoutes.generated.tsx`, import and spread:
30
-
31
- ```tsx
32
- import { applicationRouteExtensions } from '@/routes/applicationRoutes.generated';
33
-
34
- const applicationRoutes: ApplicationRouteExtensions = {
35
- ...applicationRouteExtensions,
36
- // additional manual routes if needed...
37
- };
38
- ```
39
-
40
- If no generated file exists, add routes directly to the existing `applicationRoutes` object.
41
-
42
- ---
43
-
44
- ## Step 4b: Detect App.tsx Routing Pattern
45
-
46
- Read App.tsx and detect which pattern is used:
47
-
48
- ### Pattern A: applicationRoutes Object
49
-
50
- **If App.tsx contains:** `applicationRoutes: ApplicationRouteExtensions`
51
-
52
- → Add routes to `applicationRoutes.{application}[]` with **RELATIVE** paths (no leading `/`)
53
-
54
- ```tsx
55
- const applicationRoutes: ApplicationRouteExtensions = {
56
- 'human-resources': [
57
- // existing routes...
58
- { path: '{module_kebab}/{section_kebab}', element: <{EntityName}ListPage /> },
59
- { path: '{module_kebab}/{section_kebab}/create', element: <Create{EntityName}Page /> },
60
- { path: '{module_kebab}/{section_kebab}/:id', element: <{EntityName}DetailPage /> },
61
- { path: '{module_kebab}/{section_kebab}/:id/edit', element: <Create{EntityName}Page /> },
62
-
63
- // Parent redirect routes (MANDATORY — prevents /login redirect on parent navigation)
64
- { path: '{module_kebab}', element: <Navigate to="{module_kebab}/{first_section_kebab}" replace /> },
65
- { path: '', element: <Navigate to="{first_module_kebab}/{first_section_kebab}" replace /> },
66
- ],
67
- };
68
- ```
69
-
70
- Routes are automatically injected into BOTH standard (`/{application}/...`) and tenant-prefixed (`/t/:slug/{application}/...`) route trees by `mergeRoutes()`. No manual duplication needed.
71
-
72
- #### RULE — Route Ordering in applicationRoutes
73
-
74
- > **CRITICAL:** Routes within each application key MUST follow static-before-dynamic order.
75
- > React Router matches top-to-bottom — a `:id` route placed before a `dashboard` route
76
- > will match `dashboard` as an `id` parameter → 404.
77
-
78
- ```tsx
79
- const applicationRoutes: ApplicationRouteExtensions = {
80
- 'human-resources': [
81
- // ✅ CORRECT ORDER — static before dynamic
82
- { path: 'employees', element: <EmployeesPage /> },
83
- { path: 'employees/create', element: <CreateEmployeePage /> },
84
- { path: 'employees/dashboard', element: <EmployeeDashboardPage /> },
85
- { path: 'employees/:id', element: <EmployeeDetailPage /> },
86
- { path: 'employees/:id/edit', element: <EditEmployeePage /> },
87
-
88
- // Redirect routes ALWAYS LAST
89
- { path: '', element: <Navigate to="employees" replace /> },
90
- ],
91
- };
92
- ```
93
-
94
- ```tsx
95
- // ❌ FORBIDDEN — :id before static routes
96
- 'human-resources': [
97
- { path: 'employees/:id', element: <EmployeeDetailPage /> }, // ← WRONG: catches 'dashboard'
98
- { path: 'employees/dashboard', element: <DashboardPage /> }, // ← NEVER REACHED
99
- ]
100
- ```
101
-
102
- See `smartstack-layers.md` "RULE — Frontend Route Ordering" for the full ordering specification.
103
- POST-CHECK C49 detects and BLOCKS this anti-pattern.
104
-
105
- #### Custom Applications (Pattern A)
106
-
107
- Custom application keys (any key **not** in the built-in list: `administration`, `support`, `user`, `api`) are fully supported in `applicationRoutes`. `mergeRoutes()` automatically:
108
-
109
- 1. Creates a new route entry wrapped in `<AppLayout />`
110
- 2. Injects it into **both** standard (`/{app-key}/...`) and tenant-prefixed (`/t/:slug/{app-key}/...`) trees, inside `TenantRouteWrapper > RouteGuard > LicenseGuard`
111
- 3. Generates automatic parent redirect routes (e.g., `employees` → `employees/management`)
112
-
113
- No need to use Pattern B for custom applications — Pattern A handles everything automatically.
114
-
115
- ### Pattern B: JSX Routes
116
-
117
- **If App.tsx contains:** `<Route path="/{application}" element={<{Layout} />}>`
118
-
119
- → Insert `<Route>` children inside the Layout wrapper:
120
-
42
+ Imported once in `main.tsx`:
121
43
  ```tsx
122
- <Route path="/human-resources" element={<AppLayout />}>
123
- {/* ... existing routes ... */}
124
- <Route path="{module_kebab}" element={<{EntityName}Page />} />
125
- </Route>
44
+ import './extensions/componentRegistry.generated';
126
45
  ```
127
46
 
128
- **ALSO add the same routes inside the tenant-prefixed block:**
129
-
130
- Find `<Route path="/t/:slug">` and add the **same route entries** there.
131
-
132
47
  ---
133
48
 
134
- ## Step 4b.5: Verify mergeRoutes() Call (BLOCKING)
49
+ ## For Client SDK Pages
135
50
 
136
- **BEFORE modifying routes, READ App.tsx and verify the `mergeRoutes()` call has 2 parameters.**
51
+ Clients register their own pages directly:
137
52
 
138
- ✅ Correct:
139
53
  ```tsx
140
- const routes = mergeRoutes(clientRoutes, applicationRoutes);
141
- ```
54
+ import { PageRegistry } from '@atlashub/smartstack';
55
+ import { lazy } from 'react';
142
56
 
143
- If you see only 1 parameter:
144
- ```tsx
145
- const routes = mergeRoutes(clientRoutes);
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')));
146
60
  ```
147
61
 
148
- Add the `applicationRoutes` object and pass it as 2nd parameter.
149
- Without it, ALL application routes are silently ignored → blank page or /login redirect.
150
-
151
- **NEVER remove the `applicationRoutes` parameter or the `ApplicationRouteExtensions` import.**
152
-
153
- ---
154
-
155
- ## Step 4c: Application-to-Layout Mapping
156
-
157
- | Application prefix | Layout Component | Route path |
158
- |---------|------------------|------------|
159
- | `administration.*` | `AppLayout` | `/administration` |
160
- | `*` (business apps) | `AppLayout` | `/{application}` |
161
- | `myspace.*` | `AppLayout` | `/myspace` |
62
+ Navigation entries are created in DB (via admin UI or seed data).
63
+ DynamicRouter does the junction automatically.
162
64
 
163
65
  ---
164
66
 
165
- ## Step 4d: Verify Wiring
67
+ ## Verification
166
68
 
167
69
  ```
168
70
  Tool: mcp__smartstack__validate_frontend_routes
@@ -170,68 +72,17 @@ Args:
170
72
  scope: "routes"
171
73
  ```
172
74
 
173
- If `appWiring.issues` is not empty, fix the wiring before proceeding.
174
-
175
- ---
176
-
177
- ## Step 4e: Parent Redirect Routes (MANDATORY)
178
-
179
- **CRITICAL:** 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.
180
-
181
- For each application, you MUST add:
182
-
183
- 1. **Application root redirect** — redirects `/{application}` to the first module/section:
184
- ```tsx
185
- { path: '', element: <Navigate to="{first_module}/{first_section}" replace /> }
186
- ```
187
-
188
- 2. **Module redirect** (if modules have sections) — redirects `/{application}/{module}` to first section:
189
- ```tsx
190
- { path: '{module}', element: <Navigate to="{module}/{first_section}" replace /> }
191
- ```
192
-
193
- **Example:** For NavRoutes `human-resources.employees.management` and `human-resources.employees.departments`:
194
- ```tsx
195
- { path: 'employees', element: <Navigate to="employees/management" replace /> },
196
- { path: '', element: <Navigate to="employees/management" replace /> },
197
- ```
198
-
199
- The `to` prop is resolved relative to the **parent route** (`/{application}`), so always use the full path from the application root.
200
-
201
- > Note: `scaffold_routes` with `outputFormat: "applicationRoutes"` generates these redirects automatically.
202
-
203
- ---
204
-
205
- ## Forbidden Patterns (BOTH patterns)
206
-
207
- - Adding application routes to `clientRoutes[]` with absolute paths — `clientRoutes` is ONLY for routes outside SmartStack applications (e.g., `/about`, `/pricing`)
208
- - Adding routes OUTSIDE the Layout wrapper (shell will not render)
209
- - Using `createBrowserRouter` (SmartStack uses `useRoutes()` + `mergeRoutes()`)
210
- - Adding custom application routes to `clientRoutes[]` with absolute paths:
211
- ```tsx
212
- // ❌ WRONG — bypasses RouteGuard + TenantLayout + AppLayout → /login redirect
213
- const clientRoutes: RouteConfig[] = [
214
- { path: '/human-resources/employees/management', element: <EmployeePage /> },
215
- ];
216
- ```
217
- Custom application routes MUST go in `applicationRoutes` with RELATIVE paths:
218
- ```tsx
219
- // ✅ CORRECT
220
- const applicationRoutes: ApplicationRouteExtensions = {
221
- 'human-resources': [
222
- { path: 'employees/management', element: <EmployeePage /> },
223
- ],
224
- };
225
- ```
226
- - Removing 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
227
80
 
228
81
  ---
229
82
 
230
- ## Verification Checklist
83
+ ## Legacy Patterns (DEPRECATED)
231
84
 
232
- - [ ] Routes are inside the AppLayout wrapper
233
- - [ ] Routes use NESTED structure (not flat)
234
- - [ ] Application kebab-case matches navigation seed data
235
- - [ ] Both standard and tenant-prefixed blocks have routes (if using Pattern B)
236
- - [ ] Page components are imported at top of App.tsx
237
- - [ ] `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.
@@ -73,21 +73,21 @@ Verify exactly **4 language files** exist with identical key structures:
73
73
 
74
74
  ### 5. Route Check (BLOCKING)
75
75
 
76
- Verify routes are:
77
- - **INSIDE** the AppLayout wrapper
78
- - **NESTED** (not flat)
76
+ Verify routes are registered:
77
+ - **v3.7+ (DynamicRouter):** PageRegistry.register() exists in componentRegistry.generated.ts
78
+ - **Legacy:** inside Layout wrapper, nested, correct path convention
79
79
  - Following path convention: `/{application_kebab}/{module_kebab}` (kebab-case)
80
80
 
81
81
  ### 5b. Route Wiring Check (BLOCKING)
82
82
 
83
- Verify routes are actually wired into App.tsx (not just generated in standalone files):
83
+ **v3.7+ (DynamicRouter):** Verify PageRegistry registration:
84
84
 
85
- 1. Open `App.tsx` (or `main.tsx`)
86
- 2. Verify the new route path appears **inside** the correct Layout wrapper
87
- 3. Verify the route also appears inside the **tenant-prefixed** block (`/t/:slug/...`)
88
- 4. Verify the page component is imported (lazy-loaded) at the top of the file
85
+ 1. Open `componentRegistry.generated.ts`
86
+ 2. Verify new pages have `PageRegistry.register()` calls with matching componentKeys
87
+ 3. Verify `main.tsx` imports `./extensions/componentRegistry.generated`
88
+ 4. DynamicRouter resolves routes automatically no App.tsx wiring needed
89
89
 
90
- **If routes are only in `applicationRoutes.generated.tsx` or `routes/index.tsx` but NOT in App.tsx, the routes will NOT work at runtime — page will be BLANK.**
90
+ **Legacy:** Verify routes are wired into App.tsx (inside Layout wrapper + tenant block).
91
91
 
92
92
  Run validation:
93
93
  ```
@@ -96,7 +96,7 @@ Args:
96
96
  scope: "routes"
97
97
  ```
98
98
 
99
- If `appWiring.issues` is not empty, fix the wiring before proceeding.
99
+ If validation returns issues, fix before proceeding.
100
100
 
101
101
  ### 5c. Route Kebab-Case Check (BLOCKING)
102
102
 
@@ -110,7 +110,7 @@ Scan App.tsx route paths for non-kebab-case segments:
110
110
 
111
111
  **Verification steps:**
112
112
 
113
- 1. Extract all route path strings from App.tsx (both `applicationRoutes` and `<Route path="...">`)
113
+ 1. Extract all route keys from `componentRegistry.generated.ts` (v3.7+) or App.tsx (`applicationRoutes` / `<Route path="...">`)
114
114
  2. For each multi-word path segment, verify it uses hyphens (kebab-case)
115
115
  3. Cross-reference route paths with navigation seed data routes to ensure exact match
116
116
  4. Single-word segments are fine as-is (e.g., `employees`, `products`)
@@ -103,23 +103,33 @@ Args:
103
103
  options:
104
104
  includeGuards: true
105
105
  generateRegistry: true
106
- outputFormat: "applicationRoutes"
106
+ outputFormat: "componentRegistry"
107
107
  ```
108
108
 
109
109
  This generates:
110
- - `navRoutes.generated.ts` - Route registry (NavRoute to API/web path mapping)
111
- - `applicationRoutes.generated.tsx` - Route fragments grouped by context with page imports
110
+ - `navRoutes.generated.ts` Route registry (NavRoute to API/web path mapping)
111
+ - `componentRegistry.generated.ts` PageRegistry.register() calls for DynamicRouter
112
112
 
113
- ### 4. Wire Routes to App.tsx (BLOCKING)
113
+ ### 4. Verify PageRegistry Registration
114
114
 
115
- See [references/frontend-route-wiring-app-tsx.md](../references/frontend-route-wiring-app-tsx.md) for:
116
- - Step 4a: Import page components (lazy)
117
- - Step 4a.5: Import generated route extensions (if scaffold_routes was used)
118
- - Step 4b: Detect App.tsx routing pattern (Pattern A vs Pattern B)
119
- - Step 4b.5: Verify mergeRoutes() has 2 parameters (BLOCKING)
120
- - Step 4c: Application-to-Layout mapping table
121
- - Step 4d: Route wiring verification
122
- - Forbidden patterns (absolute paths in clientRoutes, outside Layout, missing 2nd param)
115
+ After `scaffold_routes` generates the files:
116
+
117
+ 1. **Verify `componentRegistry.generated.ts`** contains `PageRegistry.register()` calls
118
+ for each new page component
119
+ 2. **Verify `main.tsx`** imports `./extensions/componentRegistry.generated`
120
+ (this should already be present — check once)
121
+ 3. **Verify navigation seed data** has `ComponentKey` values matching the registered keys
122
+ (e.g., seed Route="/administration/users" ComponentKey="administration.users")
123
+
124
+ No manual App.tsx wiring is needed — DynamicRouter resolves routes automatically
125
+ from the API menu response + PageRegistry at runtime.
126
+
127
+ Verification:
128
+ ```
129
+ Tool: mcp__smartstack__validate_frontend_routes
130
+ Args:
131
+ scope: "routes"
132
+ ```
123
133
 
124
134
  ### 5-6. Verify i18n & Present Output
125
135
 
@@ -157,10 +167,11 @@ See [references/frontend-verification.md](../references/frontend-verification.md
157
167
 
158
168
  - React component generated
159
169
  - API client generated with types
160
- - Routes updated (nested structure)
161
- - Routes wired in App.tsx (standard + tenant blocks)
170
+ - PageRegistry entries generated (componentRegistry.generated.ts)
171
+ - navRoutes.generated.ts updated
172
+ - Navigation seed data has matching componentKeys
162
173
  - i18n files created (4 languages)
163
- - Post-generation verification passed (all 7 checks + route wiring check)
174
+ - Post-generation verification passed
164
175
  - Proceeded to step-06-migration.md
165
176
 
166
177
  ## FAILURE MODES
@@ -2,6 +2,10 @@
2
2
 
3
3
  > These templates generate React/TypeScript code for new applications/modules.
4
4
 
5
+ > **DEPRECATED (v3.7+):** Pattern A (mergeRoutes) and Pattern B (JSX Routes) below
6
+ > are replaced by PageRegistry.register() + DynamicRouter.
7
+ > See references/frontend-route-wiring-app-tsx.md for the current pattern.
8
+
5
9
  ---
6
10
 
7
11
  ## FRONTEND ARCHITECTURE
@@ -113,7 +113,7 @@ COMPARISON POINTS: {total}
113
113
  [OK] index.css — @custom-variant dark present
114
114
  [OK] DependencyInjection.Application — MediatR warning present
115
115
  [OK] DependencyInjection.Infrastructure — SQL Server pattern matches
116
- [SKIP] App.tsx — Intentionally different (mergeRoutes pattern)
116
+ [SKIP] App.tsx — Intentionally different (client uses mergeRoutes legacy or PageRegistry+DynamicRouter)
117
117
  [SKIP] ExtensionsDbContext — Intentionally simplified
118
118
 
119
119
  --------------------------------------------------------------------------------
@@ -161,7 +161,7 @@ These differences are **by design** and should always be marked `[SKIP]`:
161
161
 
162
162
  | File/Pattern | Reason |
163
163
  |---|---|
164
- | `App.tsx` — `mergeRoutes` + `SmartStackProvider` | Client projects use extension routing pattern, not platform routing |
164
+ | `App.tsx` — routing pattern (`mergeRoutes` legacy or `PageRegistry`+`DynamicRouter` v3.7+) | Client projects use their own routing entry point, not platform routing |
165
165
  | `ExtensionsDbContext` | Intentionally simplified vs `CoreDbContext` — different architectural role |
166
166
  | `api.ts` | Re-exports SmartStack client — wrapper pattern is correct |
167
167
  | `DependencyInjection.Infrastructure.cs` | SQL Server connection pattern identical by design |
@@ -208,7 +208,7 @@ These comparisons should **always** return `[SKIP]` — differences are by desig
208
208
 
209
209
  | Item | Reason |
210
210
  |---|---|
211
- | `App.tsx` | Client uses `mergeRoutes` + `SmartStackProvider`; app uses direct routing |
211
+ | `App.tsx` | Client uses `mergeRoutes` (legacy) or `PageRegistry`+`DynamicRouter` (v3.7+); app uses direct routing |
212
212
  | `api.ts` | Client re-exports SmartStack client — wrapper pattern is correct |
213
213
  | `ExtensionsDbContext` | Intentionally simplified vs `CoreDbContext` |
214
214
  | `GlobalUsings.cs` | App has platform-wide usings; client has minimal set |