@atlashub/smartstack-cli 3.22.0 → 3.24.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/mcp-entry.mjs +143 -174
- package/dist/mcp-entry.mjs.map +1 -1
- package/package.json +1 -1
- package/templates/mcp-scaffolding/component.tsx.hbs +21 -1
- package/templates/skills/apex/SKILL.md +21 -0
- package/templates/skills/apex/references/smartstack-api.md +507 -0
- package/templates/skills/apex/references/smartstack-frontend.md +1081 -0
- package/templates/skills/apex/references/smartstack-layers.md +166 -20
- package/templates/skills/apex/steps/step-00-init.md +27 -14
- package/templates/skills/apex/steps/step-01-analyze.md +45 -3
- package/templates/skills/apex/steps/step-02-plan.md +5 -1
- package/templates/skills/apex/steps/step-03-execute.md +51 -9
- package/templates/skills/apex/steps/step-04-validate.md +251 -0
- package/templates/skills/apex/steps/step-05-examine.md +7 -0
- package/templates/skills/apex/steps/step-07-tests.md +48 -5
- package/templates/skills/business-analyse/_shared.md +6 -6
- package/templates/skills/business-analyse/patterns/suggestion-catalog.md +1 -1
- package/templates/skills/business-analyse/questionnaire/07-ui.md +3 -3
- package/templates/skills/business-analyse/references/cadrage-pre-analysis.md +1 -1
- package/templates/skills/business-analyse/references/entity-architecture-decision.md +3 -3
- package/templates/skills/business-analyse/references/handoff-file-templates.md +13 -5
- package/templates/skills/business-analyse/references/spec-auto-inference.md +14 -14
- package/templates/skills/business-analyse/steps/step-01-cadrage.md +2 -2
- package/templates/skills/business-analyse/steps/step-02-decomposition.md +1 -1
- package/templates/skills/business-analyse/steps/step-03a1-setup.md +2 -2
- package/templates/skills/business-analyse/steps/step-03b-ui.md +2 -1
- package/templates/skills/business-analyse/steps/step-05a-handoff.md +15 -4
- package/templates/skills/business-analyse/templates/tpl-frd.md +2 -2
- package/templates/skills/business-analyse/templates-frd.md +2 -2
- package/templates/skills/ralph-loop/references/category-rules.md +45 -7
- package/templates/skills/ralph-loop/references/compact-loop.md +2 -2
- package/templates/skills/ralph-loop/references/core-seed-data.md +10 -0
- package/templates/skills/ralph-loop/steps/step-02-execute.md +110 -1
- package/templates/skills/validate-feature/steps/step-05-db-validation.md +86 -1
|
@@ -17,8 +17,9 @@
|
|
|
17
17
|
| Validate | MCP `validate_conventions` |
|
|
18
18
|
|
|
19
19
|
**Rules:**
|
|
20
|
-
- Inherit `
|
|
21
|
-
-
|
|
20
|
+
- Inherit `BaseEntity`, implement `ITenantEntity` + `IAuditableEntity`
|
|
21
|
+
- See `references/smartstack-api.md` for exact BaseEntity API (Id, CreatedAt, UpdatedAt only)
|
|
22
|
+
- No Code/IsDeleted/RowVersion in BaseEntity — add business properties yourself
|
|
22
23
|
- Domain events for state changes
|
|
23
24
|
- Value objects for composite values
|
|
24
25
|
|
|
@@ -49,7 +50,8 @@
|
|
|
49
50
|
|
|
50
51
|
## Layer 1 — Application (parallel with API)
|
|
51
52
|
|
|
52
|
-
**Services:** `Application/Services/{ContextPascal}/{App}/{Module}/`
|
|
53
|
+
**Services:** `Application/Services/{ContextPascal}/{App}/{Module}/` (interface)
|
|
54
|
+
**Service impls:** `Infrastructure/Services/{ContextPascal}/{App}/{Module}/` (implementation)
|
|
53
55
|
**DTOs:** `Application/DTOs/{ContextPascal}/{App}/{Module}/`
|
|
54
56
|
**Validators:** `Application/Validators/{ContextPascal}/{App}/{Module}/`
|
|
55
57
|
|
|
@@ -60,10 +62,13 @@
|
|
|
60
62
|
| Validate | MCP `validate_conventions` |
|
|
61
63
|
|
|
62
64
|
**Rules:**
|
|
65
|
+
- **ALL services MUST inject `ICurrentUser` and filter by `TenantId`** (see `smartstack-api.md` Service Pattern)
|
|
66
|
+
- **ALL services MUST inject `ILogger<T>`** for production diagnostics
|
|
63
67
|
- CQRS with MediatR
|
|
64
68
|
- FluentValidation for all commands
|
|
65
69
|
- DTOs separate from domain entities
|
|
66
70
|
- Service interfaces in Application, implementations in Infrastructure
|
|
71
|
+
- **FORBIDDEN:** `tenantId: Guid.Empty`, queries without TenantId filter, services without ICurrentUser
|
|
67
72
|
|
|
68
73
|
---
|
|
69
74
|
|
|
@@ -96,40 +101,107 @@
|
|
|
96
101
|
|
|
97
102
|
**Folder:** `Infrastructure/Persistence/Seeding/Data/{ModulePascal}/`
|
|
98
103
|
|
|
104
|
+
> **Detailed templates:** See ralph-loop `references/core-seed-data.md` for complete C# code templates.
|
|
105
|
+
> Navigation hierarchy: Context → Application → Module → Section → Resource (ALL levels need seed data).
|
|
106
|
+
|
|
99
107
|
| Action | Tool |
|
|
100
108
|
|--------|------|
|
|
101
109
|
| Generate permissions | MCP `generate_permissions` (PRIMARY) |
|
|
102
|
-
| Navigation seed |
|
|
103
|
-
| Roles seed |
|
|
104
|
-
| Provider |
|
|
105
|
-
|
|
106
|
-
### Seed Data Chain (
|
|
107
|
-
|
|
108
|
-
1. **
|
|
109
|
-
2. **
|
|
110
|
-
3. **
|
|
111
|
-
4. **
|
|
112
|
-
5. **
|
|
113
|
-
|
|
110
|
+
| Navigation seed | Templates below |
|
|
111
|
+
| Roles seed | Templates below |
|
|
112
|
+
| Provider | Templates below |
|
|
113
|
+
|
|
114
|
+
### Seed Data Chain (7 files minimum)
|
|
115
|
+
|
|
116
|
+
1. **NavigationApplicationSeedData.cs** — Application-level navigation entry (MUST be first)
|
|
117
|
+
2. **NavigationModuleSeedData.cs** — Deterministic GUIDs (SHA256), 4 languages (fr, en, it, de)
|
|
118
|
+
3. **NavigationSectionSeedData.cs** — Section-level navigation (if sections defined)
|
|
119
|
+
4. **NavigationResourceSeedData.cs** — Resource-level navigation (if resources defined)
|
|
120
|
+
5. **PermissionsSeedData.cs** — MCP `generate_permissions` first, fallback template
|
|
121
|
+
6. **RolesSeedData.cs** — Context-based: Admin=CRUD, Manager=CRU, Contributor=CR, Viewer=R
|
|
122
|
+
7. **{App}SeedDataProvider.cs** — Implements IClientSeedDataProvider
|
|
123
|
+
- `SeedNavigationAsync()` — seeds Application → Module → Section → Resource + translations
|
|
124
|
+
- `SeedPermissionsAsync()` + `SeedRolePermissionsAsync()`
|
|
114
125
|
- DI: `services.AddScoped<IClientSeedDataProvider, {App}SeedDataProvider>()`
|
|
115
126
|
|
|
127
|
+
### Deterministic GUID Pattern
|
|
128
|
+
|
|
129
|
+
```csharp
|
|
130
|
+
// Use SHA256 for deterministic GUIDs (reproducible across environments)
|
|
131
|
+
public static readonly Guid ModuleId = GenerateDeterministicGuid("nav-module-{app}-{module}");
|
|
132
|
+
|
|
133
|
+
private static Guid GenerateDeterministicGuid(string input)
|
|
134
|
+
{
|
|
135
|
+
var hash = System.Security.Cryptography.SHA256.HashData(
|
|
136
|
+
System.Text.Encoding.UTF8.GetBytes(input));
|
|
137
|
+
var bytes = new byte[16];
|
|
138
|
+
Array.Copy(hash, bytes, 16);
|
|
139
|
+
return new Guid(bytes);
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Route Convention (CRITICAL — Full Paths Required)
|
|
144
|
+
|
|
145
|
+
> **Routes stored in DB drive the platform menu AND application-tracking.**
|
|
146
|
+
> Short routes (e.g., `humanresources`) cause **400 Bad Request** on every page navigation.
|
|
147
|
+
|
|
148
|
+
**Route format: `/{context}/{app-kebab}/{module-kebab}/{section-kebab}`**
|
|
149
|
+
|
|
150
|
+
| Level | Code (C#) | Route (DB) |
|
|
151
|
+
|-------|-----------|-----------|
|
|
152
|
+
| Application | `humanresources` | `/business/human-resources` |
|
|
153
|
+
| Module | `employees` | `/business/human-resources/employees` |
|
|
154
|
+
| Section | `departments` | `/business/human-resources/employees/departments` |
|
|
155
|
+
| Resource | `export` | `/business/human-resources/employees/departments/export` |
|
|
156
|
+
|
|
157
|
+
**Platform examples (verified from SmartStack.app):**
|
|
158
|
+
- `/platform/administration` (not `administration`)
|
|
159
|
+
- `/platform/administration/users` (not `users`)
|
|
160
|
+
- `/personal/myspace/profile` (not `profile`)
|
|
161
|
+
|
|
162
|
+
- PascalCase for C# code identifiers (`HumanResources`)
|
|
163
|
+
- **kebab-case** for ALL URL routes in seed data (`human-resources`)
|
|
164
|
+
- **Routes MUST start with `/`** and include full parent hierarchy
|
|
165
|
+
- Helper: `ToKebabCase()` transforms PascalCase → kebab-case
|
|
166
|
+
|
|
167
|
+
```csharp
|
|
168
|
+
private static string ToKebabCase(string value)
|
|
169
|
+
=> System.Text.RegularExpressions.Regex.Replace(value, "(?<!^)([A-Z])", "-$1").ToLowerInvariant();
|
|
170
|
+
|
|
171
|
+
// Route construction:
|
|
172
|
+
var appRoute = $"/{ToKebabCase(contextCode)}/{ToKebabCase(appCode)}";
|
|
173
|
+
// → "/business/human-resources"
|
|
174
|
+
|
|
175
|
+
var moduleRoute = $"{appRoute}/{ToKebabCase(moduleCode)}";
|
|
176
|
+
// → "/business/human-resources/employees"
|
|
177
|
+
|
|
178
|
+
var sectionRoute = $"{moduleRoute}/{ToKebabCase(sectionCode)}";
|
|
179
|
+
// → "/business/human-resources/employees/departments"
|
|
180
|
+
```
|
|
181
|
+
|
|
116
182
|
**FORBIDDEN:**
|
|
117
183
|
- `Guid.NewGuid()` → use deterministic GUIDs (SHA256)
|
|
118
184
|
- Missing translations (must have fr, en, it, de)
|
|
119
185
|
- Empty seed classes with no seeding logic
|
|
186
|
+
- PascalCase in route URLs → always kebab-case
|
|
187
|
+
- Missing NavigationApplicationSeedData → menu invisible
|
|
188
|
+
- **Short routes without `/` prefix** → `"humanresources"` must be `"/business/human-resources"`
|
|
189
|
+
- **Routes without parent hierarchy** → `"employees"` must be `"/business/human-resources/employees"`
|
|
120
190
|
|
|
121
191
|
---
|
|
122
192
|
|
|
123
193
|
## Layer 2 — Frontend (parallel with I18n)
|
|
124
194
|
|
|
195
|
+
> **Detailed patterns:** See `references/smartstack-frontend.md` for complete code templates.
|
|
196
|
+
|
|
125
197
|
**Pages:** `src/pages/{ContextPascal}/{AppPascal}/{Module}/`
|
|
126
198
|
**Components:** `src/components/{Module}/`
|
|
127
199
|
|
|
128
200
|
| Action | Tool |
|
|
129
201
|
|--------|------|
|
|
130
202
|
| API client | MCP `scaffold_api_client` |
|
|
131
|
-
| Routes | MCP `scaffold_routes` |
|
|
132
|
-
| Complex pages | /ui-components skill |
|
|
203
|
+
| Routes | MCP `scaffold_routes` (outputFormat: `clientRoutes`) |
|
|
204
|
+
| Complex pages | /ui-components skill + `smartstack-frontend.md` patterns |
|
|
133
205
|
| Validate routes | MCP `validate_frontend_routes` |
|
|
134
206
|
|
|
135
207
|
**Layout mapping:**
|
|
@@ -140,21 +212,95 @@
|
|
|
140
212
|
| `business.*` | `BusinessLayout` | `/business` |
|
|
141
213
|
| `personal.*` | `UserLayout` | `/personal/myspace` |
|
|
142
214
|
|
|
215
|
+
### Lazy Loading (MANDATORY)
|
|
216
|
+
|
|
217
|
+
ALL page components MUST be lazy-loaded using `React.lazy()`:
|
|
218
|
+
|
|
219
|
+
```tsx
|
|
220
|
+
const EmployeesPage = lazy(() =>
|
|
221
|
+
import('@/pages/Business/HumanResources/Employees/EmployeesPage')
|
|
222
|
+
.then(m => ({ default: m.EmployeesPage }))
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
// Route element — ALWAYS wrap with Suspense
|
|
226
|
+
element: <Suspense fallback={<PageLoader />}><EmployeesPage /></Suspense>
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Page Structure Pattern
|
|
230
|
+
|
|
231
|
+
All pages MUST follow: hooks → useEffect(load) → loading state → error state → content.
|
|
232
|
+
|
|
233
|
+
```tsx
|
|
234
|
+
// 1. Hooks at top
|
|
235
|
+
const { t } = useTranslation(['{module}']);
|
|
236
|
+
// 2. State
|
|
237
|
+
const [loading, setLoading] = useState(true);
|
|
238
|
+
// 3. useCallback + useEffect for data loading
|
|
239
|
+
// 4. if (loading) return <Loader2 spinner />
|
|
240
|
+
// 5. if (error) return <error UI with retry>
|
|
241
|
+
// 6. return <content with CSS variables>
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Components & CSS
|
|
245
|
+
|
|
143
246
|
**Components:** SmartTable, SmartFilter, EntityCard, SmartForm, StatCard (NEVER raw HTML)
|
|
144
|
-
**CSS:** Variables only → `bg-[var(--bg-card)]`, `text-[var(--text-primary)]`
|
|
247
|
+
**CSS:** Variables only → `bg-[var(--bg-card)]`, `text-[var(--text-primary)]`, `border-[var(--border-color)]`
|
|
248
|
+
**Loader:** `Loader2` from `lucide-react` for spinners, `PageLoader` for Suspense fallback
|
|
249
|
+
|
|
250
|
+
### FK Fields in Forms (CRITICAL)
|
|
251
|
+
|
|
252
|
+
Any entity property that is a FK Guid (e.g., `EmployeeId`, `DepartmentId`) MUST use the `EntityLookup` component — NEVER a plain text input. Users cannot type GUIDs manually.
|
|
253
|
+
|
|
254
|
+
```tsx
|
|
255
|
+
// CORRECT — EntityLookup for FK field
|
|
256
|
+
<EntityLookup
|
|
257
|
+
apiEndpoint="/api/business/human-resources/employees"
|
|
258
|
+
value={formData.employeeId}
|
|
259
|
+
onChange={(id) => handleChange('employeeId', id)}
|
|
260
|
+
label={t('module:form.employee', 'Employee')}
|
|
261
|
+
mapOption={(item) => ({ id: item.id, label: item.name, sublabel: item.code })}
|
|
262
|
+
required
|
|
263
|
+
/>
|
|
264
|
+
|
|
265
|
+
// WRONG — plain text input for FK GUID
|
|
266
|
+
<input type="text" value={formData.employeeId} placeholder="Enter employee ID" />
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
**Backend requirement:** Each target entity's GetAll endpoint MUST accept `?search=` parameter. See `smartstack-api.md` Service Pattern.
|
|
270
|
+
|
|
271
|
+
See `references/smartstack-frontend.md` section 6 for the full `EntityLookup` component definition and usage patterns.
|
|
145
272
|
|
|
146
273
|
**FORBIDDEN:**
|
|
147
274
|
- `src/pages/{Module}/` (flat, missing Context/App)
|
|
148
275
|
- `import axios` → use `@/services/api/apiClient`
|
|
149
276
|
- `<table>` → use SmartTable
|
|
150
|
-
-
|
|
277
|
+
- `<input type="text">` for FK Guid fields → use `EntityLookup`
|
|
278
|
+
- Placeholder "Enter ID" or "Enter GUID" → use `EntityLookup`
|
|
279
|
+
- Hardcoded Tailwind colors (`bg-white`, `text-gray-900`) → use CSS variables
|
|
280
|
+
- Static page imports in route files → use `React.lazy()`
|
|
281
|
+
- `<Suspense>` without `fallback` prop
|
|
151
282
|
- Only fr/en → MUST have 4 languages
|
|
283
|
+
- `t('key')` without namespace prefix → use `t('ns:key', 'fallback')`
|
|
284
|
+
- Hardcoded user-facing strings in JSX → use `t()`
|
|
152
285
|
|
|
153
286
|
---
|
|
154
287
|
|
|
155
288
|
## Layer 2 — I18n
|
|
156
289
|
|
|
157
|
-
|
|
290
|
+
> **Template:** See `references/smartstack-frontend.md` Section 2 for complete JSON template.
|
|
291
|
+
|
|
292
|
+
4 JSON files per module namespace: fr, en, it, de — identical key structures.
|
|
293
|
+
|
|
294
|
+
**Location:** `src/i18n/locales/{lang}/{module}.json`
|
|
295
|
+
|
|
296
|
+
**Required keys:** `title`, `description`, `actions`, `labels`, `columns`, `form`, `errors`, `validation`, `messages`, `empty`
|
|
297
|
+
|
|
298
|
+
**Usage pattern:**
|
|
299
|
+
```tsx
|
|
300
|
+
const { t } = useTranslation(['{module}']);
|
|
301
|
+
t('{module}:title', 'Module Title') // ALWAYS with fallback
|
|
302
|
+
t('{module}:actions.create', 'Create entity') // ALWAYS with namespace prefix
|
|
303
|
+
```
|
|
158
304
|
|
|
159
305
|
---
|
|
160
306
|
|
|
@@ -7,6 +7,14 @@ next_step: steps/step-01-analyze.md
|
|
|
7
7
|
|
|
8
8
|
# Step 0: Initialize
|
|
9
9
|
|
|
10
|
+
**Before anything else**, display the version banner:
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
═══════════════════════════════════════════════════════════════
|
|
14
|
+
SmartStack APEX — v{{SMARTSTACK_VERSION}}
|
|
15
|
+
═══════════════════════════════════════════════════════════════
|
|
16
|
+
```
|
|
17
|
+
|
|
10
18
|
## LOAD SHARED
|
|
11
19
|
|
|
12
20
|
Read `_shared.md` for SmartStack detection patterns and MCP tools reference.
|
|
@@ -133,20 +141,25 @@ IF save_mode:
|
|
|
133
141
|
## 7. Display Context Summary
|
|
134
142
|
|
|
135
143
|
```
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
144
|
+
═══════════════════════════════════════════════════════════════
|
|
145
|
+
APEX INITIALIZATION COMPLETE
|
|
146
|
+
SmartStack CLI v{{SMARTSTACK_VERSION}}
|
|
147
|
+
═══════════════════════════════════════════════════════════════
|
|
148
|
+
|
|
149
|
+
| Field | Value |
|
|
150
|
+
|--------------------|----------------------------------------------|
|
|
151
|
+
| Task | {task_description} |
|
|
152
|
+
| Context | {context_code} / {app_name} / {module_code} |
|
|
153
|
+
| Sections | {sections} |
|
|
154
|
+
| PRD | {prd_path || "none"} |
|
|
155
|
+
| Feature | {feature_path || "none"} |
|
|
156
|
+
| Flags | {active_flags} |
|
|
157
|
+
| MCP | {available|degraded} |
|
|
158
|
+
| Needs migration | {yes|no} |
|
|
159
|
+
| Needs seed data | {yes|no} |
|
|
160
|
+
|
|
161
|
+
NEXT STEP: step-01-analyze
|
|
162
|
+
═══════════════════════════════════════════════════════════════
|
|
150
163
|
```
|
|
151
164
|
|
|
152
165
|
---
|
|
@@ -12,10 +12,28 @@ next_step: steps/step-02-plan.md
|
|
|
12
12
|
|
|
13
13
|
## LOAD CONDITIONALLY
|
|
14
14
|
|
|
15
|
+
- **ALWAYS** read `references/smartstack-api.md` — BaseEntity API, entity/config/controller patterns
|
|
15
16
|
- If NOT `{economy_mode}`: read `references/agent-teams-protocol.md`
|
|
16
17
|
|
|
17
18
|
---
|
|
18
19
|
|
|
20
|
+
## 0. Fresh Project Detection (Early Exit)
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
IF .smartstack/init-state.json exists:
|
|
24
|
+
Read it → check if project was recently initialized
|
|
25
|
+
Glob("src/**/Entities/**/*.cs") → count entity files
|
|
26
|
+
|
|
27
|
+
IF entity count == 0 AND no PRD AND no feature.json:
|
|
28
|
+
→ SKIP full code exploration (sections 2-3)
|
|
29
|
+
→ Declare: "Fresh project — all elements need to be CREATED"
|
|
30
|
+
→ Jump directly to section 4 (Gap Analysis) with all items marked "create"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
This saves ~2 minutes of Glob searches on an empty project.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
19
37
|
## 1. Context Sources
|
|
20
38
|
|
|
21
39
|
Read available context (in order of priority):
|
|
@@ -118,7 +136,31 @@ Identify:
|
|
|
118
136
|
|
|
119
137
|
---
|
|
120
138
|
|
|
121
|
-
## 4.
|
|
139
|
+
## 4. FK Field Detection
|
|
140
|
+
|
|
141
|
+
For each entity found (or to be created), identify FK relationships:
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
For each entity in analysis results:
|
|
145
|
+
- List properties ending in "Id" with a matching navigation property (e.g., EmployeeId + Employee)
|
|
146
|
+
- Record: { fkProperty, targetEntity, isRequired }
|
|
147
|
+
|
|
148
|
+
Output:
|
|
149
|
+
fkFields: [
|
|
150
|
+
{ entity: "TimeEntry", fkProperty: "EmployeeId", targetEntity: "Employee", isRequired: true },
|
|
151
|
+
{ entity: "TimeEntry", fkProperty: "ProjectId", targetEntity: "Project", isRequired: true }
|
|
152
|
+
]
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Why:** FK fields drive two critical downstream requirements:
|
|
156
|
+
1. **Frontend:** Each FK field MUST use `EntityLookup` component (NEVER plain text input for GUIDs)
|
|
157
|
+
2. **Backend:** Each target entity's GetAll endpoint MUST support `?search=` query parameter
|
|
158
|
+
|
|
159
|
+
These are propagated to step-02 (plan) and step-03 (execute).
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## 5. Gap Analysis
|
|
122
164
|
|
|
123
165
|
Compare what EXISTS vs what the TASK REQUIRES:
|
|
124
166
|
|
|
@@ -131,7 +173,7 @@ For each element in the task description:
|
|
|
131
173
|
|
|
132
174
|
---
|
|
133
175
|
|
|
134
|
-
##
|
|
176
|
+
## 6. Analysis Summary
|
|
135
177
|
|
|
136
178
|
```
|
|
137
179
|
**APEX SmartStack - Analysis Complete**
|
|
@@ -158,7 +200,7 @@ For each element in the task description:
|
|
|
158
200
|
|
|
159
201
|
---
|
|
160
202
|
|
|
161
|
-
##
|
|
203
|
+
## 7. Save Output (if save_mode)
|
|
162
204
|
|
|
163
205
|
Write to `{output_dir}/01-analyze.md` with analysis results.
|
|
164
206
|
|
|
@@ -63,9 +63,13 @@ For EACH file in the plan, specify HOW it will be created/modified:
|
|
|
63
63
|
| # | File | Action | Tool |
|
|
64
64
|
|---|------|--------|------|
|
|
65
65
|
| 10 | src/pages/{Ctx}/{App}/{Mod}/ListPage.tsx | create | /ui-components skill |
|
|
66
|
+
| 10b | src/pages/{Ctx}/{App}/{Mod}/CreatePage.tsx | create | /ui-components skill (EntityLookup for FK fields) |
|
|
67
|
+
| 10c | src/pages/{Ctx}/{App}/{Mod}/EditPage.tsx | create | /ui-components skill (EntityLookup for FK fields) |
|
|
66
68
|
| 11 | src/services/api/{module}Api.ts | create | MCP scaffold_api_client |
|
|
67
69
|
| 12 | src/routes/{module}.tsx | create | MCP scaffold_routes |
|
|
68
|
-
| 13 | src/locales/
|
|
70
|
+
| 13 | src/i18n/locales/{lang}/{module}.json | create | ref smartstack-frontend.md (4 languages: fr, en, it, de) |
|
|
71
|
+
|
|
72
|
+
**FK Field Guidance:** If step-01 identified `fkFields[]`, every Create/Edit page MUST use `EntityLookup` for those fields (see `smartstack-frontend.md` section 6). The corresponding backend GetAll endpoints (Layer 1) MUST support `?search=` parameter.
|
|
69
73
|
|
|
70
74
|
### Layer 3 — Tests (sequential, if -t)
|
|
71
75
|
|
|
@@ -13,6 +13,8 @@ All code goes through skills (/controller, /application, /ui-components, /efcore
|
|
|
13
13
|
|
|
14
14
|
## LOAD CONDITIONALLY
|
|
15
15
|
|
|
16
|
+
- **ALWAYS** read `references/smartstack-api.md` — BaseEntity API, entity/config/controller patterns
|
|
17
|
+
- **ALWAYS** read `references/smartstack-frontend.md` — lazy loading, i18n, page structure, CSS variables
|
|
16
18
|
- Read `references/smartstack-layers.md` for execution rules per layer
|
|
17
19
|
- If NOT `{economy_mode}` AND Layer 1 has parallel work: read `references/agent-teams-protocol.md`
|
|
18
20
|
|
|
@@ -25,7 +27,8 @@ All code goes through skills (/controller, /application, /ui-components, /efcore
|
|
|
25
27
|
```
|
|
26
28
|
For each entity to create/modify:
|
|
27
29
|
→ MCP scaffold_extension (type: "entity", target: entity_name)
|
|
28
|
-
→ Verify: inherits
|
|
30
|
+
→ Verify: inherits BaseEntity, implements ITenantEntity + IAuditableEntity
|
|
31
|
+
→ Verify entity matches patterns in references/smartstack-api.md
|
|
29
32
|
```
|
|
30
33
|
|
|
31
34
|
### EF Core Configurations
|
|
@@ -43,7 +46,7 @@ For each entity:
|
|
|
43
46
|
1. MCP suggest_migration → get standardized name
|
|
44
47
|
2. dotnet ef migrations add {Name} --project src/{Infra}.csproj --startup-project src/{Api}.csproj -o Persistence/Migrations
|
|
45
48
|
3. dotnet ef database update (if local DB)
|
|
46
|
-
4. dotnet build
|
|
49
|
+
4. dotnet build → MUST PASS
|
|
47
50
|
```
|
|
48
51
|
|
|
49
52
|
**BLOCKING:** If build fails after migration, fix EF configs before proceeding.
|
|
@@ -51,10 +54,10 @@ For each entity:
|
|
|
51
54
|
### Post-Layer 0 Build Gate
|
|
52
55
|
|
|
53
56
|
```bash
|
|
54
|
-
dotnet build
|
|
57
|
+
dotnet build
|
|
55
58
|
```
|
|
56
59
|
|
|
57
|
-
**MUST PASS before Layer 1. If
|
|
60
|
+
**MUST PASS before Layer 1. If NuGet error, run `dotnet restore` first. If file lock (MSB3021), use `--output /tmp/{project}_build`.**
|
|
58
61
|
|
|
59
62
|
---
|
|
60
63
|
|
|
@@ -64,6 +67,18 @@ dotnet build --no-restore
|
|
|
64
67
|
|
|
65
68
|
Execute each item from the plan sequentially using skills and MCP.
|
|
66
69
|
|
|
70
|
+
**For frontend tasks (economy_mode):** Follow the same rules as exec-frontend above:
|
|
71
|
+
- `MCP scaffold_api_client` → API client + types + React Query hook
|
|
72
|
+
- `MCP scaffold_routes` with `outputFormat: 'clientRoutes'` for lazy imports
|
|
73
|
+
- Pages: use `/ui-components` skill — MANDATORY for entity lists, grids, tables, dashboards
|
|
74
|
+
- **Form pages: Create `EntityCreatePage.tsx` (route: `/create`) and `EntityEditPage.tsx` (route: `/:id/edit`)**
|
|
75
|
+
- **FK FIELDS (CRITICAL):** Any Guid FK property (e.g., EmployeeId, DepartmentId) MUST use `EntityLookup` component — NEVER a plain text input. See `smartstack-frontend.md` section 6.
|
|
76
|
+
- **ZERO modals/popups/drawers for forms — ALL forms are full pages with their own URL**
|
|
77
|
+
- **Form tests: Generate `EntityCreatePage.test.tsx` and `EntityEditPage.test.tsx` (co-located)**
|
|
78
|
+
- Read `references/smartstack-frontend.md` for mandatory patterns (sections 3b + 8)
|
|
79
|
+
- Generate i18n JSON files for all 4 languages (fr, en, it, de) — `src/i18n/locales/{lang}/{module}.json`
|
|
80
|
+
- All pages must follow loading → error → content pattern with CSS variables
|
|
81
|
+
|
|
67
82
|
### If NOT economy_mode: Agent Teams (parallel)
|
|
68
83
|
|
|
69
84
|
> **Protocol:** See `references/agent-teams-protocol.md`
|
|
@@ -80,6 +95,7 @@ Spawn 2 teammates (Opus, full tools):
|
|
|
80
95
|
For each task:
|
|
81
96
|
- Application services/DTOs: MCP scaffold_extension
|
|
82
97
|
- Controllers: use /controller skill for complex, MCP scaffold_extension for simple
|
|
98
|
+
- IMPORTANT: ALL GetAll endpoints MUST support ?search= query parameter (enables EntityLookup on frontend)
|
|
83
99
|
- Seed data: MCP generate_permissions, then follow smartstack-layers.md templates
|
|
84
100
|
|
|
85
101
|
After ALL tasks done:
|
|
@@ -89,11 +105,37 @@ Spawn 2 teammates (Opus, full tools):
|
|
|
89
105
|
"Execute these Layer 1 frontend tasks for module {module_code}:
|
|
90
106
|
{list of frontend + i18n tasks from plan}
|
|
91
107
|
|
|
108
|
+
**MANDATORY: Read references/smartstack-frontend.md FIRST** — contains all required patterns.
|
|
109
|
+
|
|
92
110
|
For each task:
|
|
93
111
|
- API client: MCP scaffold_api_client
|
|
94
|
-
- Routes: MCP scaffold_routes
|
|
95
|
-
- Pages: use /ui-components skill
|
|
96
|
-
|
|
112
|
+
- Routes: MCP scaffold_routes (outputFormat: 'clientRoutes') → generates lazy imports + Suspense
|
|
113
|
+
- Pages: use /ui-components skill — MUST follow smartstack-frontend.md patterns:
|
|
114
|
+
→ React.lazy() for all page imports (named export wrapping)
|
|
115
|
+
→ <Suspense fallback={<PageLoader />}> around all lazy components
|
|
116
|
+
→ Page structure: hooks → useEffect(load) → loading → error → content
|
|
117
|
+
→ CSS variables only: bg-[var(--bg-card)], text-[var(--text-primary)]
|
|
118
|
+
→ SmartTable/SmartFilter/EntityCard (NEVER raw HTML)
|
|
119
|
+
- **FORM PAGES (CRITICAL):** Create/Edit forms are FULL PAGES with own routes:
|
|
120
|
+
→ EntityCreatePage.tsx with route /{module}/create
|
|
121
|
+
→ EntityEditPage.tsx with route /{module}/:id/edit
|
|
122
|
+
→ ZERO modals/popups/drawers/dialogs for forms
|
|
123
|
+
→ Back button with navigate(-1) on every form page
|
|
124
|
+
→ See smartstack-frontend.md section 3b for templates
|
|
125
|
+
- **FK FIELDS (CRITICAL):** Foreign key Guid fields (e.g., EmployeeId) MUST use EntityLookup:
|
|
126
|
+
→ NEVER render FK fields as plain text inputs — users cannot type GUIDs
|
|
127
|
+
→ Use EntityLookup from @/components/ui/EntityLookup for searchable selection
|
|
128
|
+
→ Each FK field needs: apiEndpoint, mapOption (display name), search support on backend
|
|
129
|
+
→ See smartstack-frontend.md section 6 for the full EntityLookup pattern
|
|
130
|
+
- **FORM TESTS (MANDATORY):**
|
|
131
|
+
→ EntityCreatePage.test.tsx (co-located next to page)
|
|
132
|
+
→ EntityEditPage.test.tsx (co-located next to page)
|
|
133
|
+
→ Cover: rendering, validation, submit, pre-fill, navigation, errors
|
|
134
|
+
→ See smartstack-frontend.md section 8 for test templates
|
|
135
|
+
- I18n: Generate 4 JSON files per module namespace (fr, en, it, de)
|
|
136
|
+
→ Follow JSON template from smartstack-frontend.md
|
|
137
|
+
→ Keys: actions, labels, errors, validation, columns, form, messages, empty
|
|
138
|
+
→ ALL t() calls MUST use namespace prefix + fallback: t('ns:key', 'Default text')
|
|
97
139
|
- MUST use src/pages/{Context}/{App}/{Module}/ hierarchy (NOT flat)
|
|
98
140
|
|
|
99
141
|
After ALL tasks done:
|
|
@@ -102,7 +144,7 @@ Spawn 2 teammates (Opus, full tools):
|
|
|
102
144
|
Wait for both teammates to report completion.
|
|
103
145
|
|
|
104
146
|
Build verification:
|
|
105
|
-
dotnet build
|
|
147
|
+
dotnet build (backend)
|
|
106
148
|
npm run typecheck (frontend, if applicable)
|
|
107
149
|
|
|
108
150
|
shutdown_request → shutdown_response → TeamDelete("apex-exec")
|
|
@@ -136,7 +178,7 @@ After Layer 1 completes:
|
|
|
136
178
|
- DI registration added
|
|
137
179
|
|
|
138
180
|
2. Build gate:
|
|
139
|
-
dotnet build
|
|
181
|
+
dotnet build → MUST PASS
|
|
140
182
|
npm run typecheck → MUST PASS (if frontend)
|
|
141
183
|
```
|
|
142
184
|
|