@atlashub/smartstack-cli 3.8.0 → 3.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +365 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/templates/agents/action.md +1 -0
- package/templates/agents/ba-writer.md +211 -0
- package/templates/agents/explore-codebase.md +1 -0
- package/templates/agents/explore-docs.md +1 -0
- package/templates/agents/fix-grammar.md +1 -0
- package/templates/agents/snipper.md +1 -0
- package/templates/skills/admin/SKILL.md +6 -0
- package/templates/skills/ai-prompt/SKILL.md +32 -136
- package/templates/skills/ai-prompt/steps/step-01-implementation.md +122 -0
- package/templates/skills/apex/SKILL.md +120 -0
- package/templates/skills/apex/_shared.md +86 -0
- package/templates/skills/apex/references/agent-teams-protocol.md +164 -0
- package/templates/skills/apex/references/smartstack-layers.md +173 -0
- package/templates/skills/apex/steps/step-00-init.md +156 -0
- package/templates/skills/apex/steps/step-01-analyze.md +169 -0
- package/templates/skills/apex/steps/step-02-plan.md +160 -0
- package/templates/skills/apex/steps/step-03-execute.md +166 -0
- package/templates/skills/apex/steps/step-04-validate.md +138 -0
- package/templates/skills/apex/steps/step-05-examine.md +124 -0
- package/templates/skills/apex/steps/step-06-resolve.md +105 -0
- package/templates/skills/apex/steps/step-07-tests.md +130 -0
- package/templates/skills/apex/steps/step-08-run-tests.md +115 -0
- package/templates/skills/application/SKILL.md +10 -0
- package/templates/skills/application/references/application-roles-template.md +227 -0
- package/templates/skills/application/references/backend-controller-hierarchy.md +58 -0
- package/templates/skills/application/references/backend-entity-seeding.md +72 -0
- package/templates/skills/application/references/backend-verification.md +88 -0
- package/templates/skills/application/references/frontend-verification.md +111 -0
- package/templates/skills/application/references/nav-fallback-procedure.md +200 -0
- package/templates/skills/application/references/provider-template.md +158 -0
- package/templates/skills/application/references/test-frontend.md +73 -0
- package/templates/skills/application/references/test-prerequisites.md +72 -0
- package/templates/skills/application/steps/step-01-navigation.md +7 -198
- package/templates/skills/application/steps/step-03-roles.md +45 -7
- package/templates/skills/application/steps/step-03b-provider.md +15 -132
- package/templates/skills/application/steps/step-04-backend.md +20 -350
- package/templates/skills/application/steps/step-05-frontend.md +12 -101
- package/templates/skills/application/steps/step-07-tests.md +12 -132
- package/templates/skills/business-analyse/SKILL.md +67 -6
- package/templates/skills/business-analyse/html/ba-interactive.html +176 -14
- package/templates/skills/business-analyse/html/src/scripts/01-data-init.js +1 -0
- package/templates/skills/business-analyse/html/src/scripts/05-render-specs.js +16 -4
- package/templates/skills/business-analyse/html/src/scripts/06-render-consolidation.js +7 -2
- package/templates/skills/business-analyse/html/src/scripts/09-export.js +103 -0
- package/templates/skills/business-analyse/html/src/scripts/10-comments.js +12 -6
- package/templates/skills/business-analyse/html/src/scripts/11-review-panel.js +24 -2
- package/templates/skills/business-analyse/html/src/styles/08-review-panel.css +12 -0
- package/templates/skills/business-analyse/html/src/template.html +1 -0
- package/templates/skills/business-analyse/references/agent-pooling-best-practices.md +477 -0
- package/templates/skills/business-analyse/references/cache-warming-strategy.md +578 -0
- package/templates/skills/business-analyse/references/cadrage-structure-cards.md +78 -0
- package/templates/skills/business-analyse/references/cadrage-vibe-coding.md +97 -0
- package/templates/skills/business-analyse/references/consolidation-structural-checks.md +92 -0
- package/templates/skills/business-analyse/references/deploy-data-build.md +121 -0
- package/templates/skills/business-analyse/references/deploy-modes.md +49 -0
- package/templates/skills/business-analyse/references/handoff-file-templates.md +119 -0
- package/templates/skills/business-analyse/references/handoff-mappings.md +81 -0
- package/templates/skills/business-analyse/references/html-data-mapping.md +10 -2
- package/templates/skills/business-analyse/references/init-schema-deployment.md +65 -0
- package/templates/skills/business-analyse/references/review-data-mapping.md +363 -0
- package/templates/skills/business-analyse/references/robustness-checks.md +538 -0
- package/templates/skills/business-analyse/references/spec-auto-inference.md +57 -0
- package/templates/skills/business-analyse/references/ui-dashboard-spec.md +85 -0
- package/templates/skills/business-analyse/references/ui-resource-cards.md +110 -0
- package/templates/skills/business-analyse/references/validate-incremental-html.md +55 -0
- package/templates/skills/business-analyse/schemas/sections/specification-schema.json +33 -1
- package/templates/skills/business-analyse/steps/step-00-init.md +186 -53
- package/templates/skills/business-analyse/steps/step-01-cadrage.md +5 -194
- package/templates/skills/business-analyse/steps/step-03a-data.md +42 -49
- package/templates/skills/business-analyse/steps/step-03b-ui.md +12 -178
- package/templates/skills/business-analyse/steps/step-03c-compile.md +71 -2
- package/templates/skills/business-analyse/steps/step-03d-validate.md +277 -48
- package/templates/skills/business-analyse/steps/step-04-consolidation.md +175 -104
- package/templates/skills/business-analyse/steps/step-05a-handoff.md +66 -438
- package/templates/skills/business-analyse/steps/step-05b-deploy.md +35 -184
- package/templates/skills/business-analyse/steps/step-05c-ralph-readiness.md +526 -0
- package/templates/skills/business-analyse/steps/step-06-review.md +277 -0
- package/templates/skills/cc-agent/references/agent-behavior-patterns.md +95 -0
- package/templates/skills/cc-agent/steps/step-02-generate.md +5 -78
- package/templates/skills/check-version/SKILL.md +7 -0
- package/templates/skills/controller/references/controller-code-templates.md +159 -0
- package/templates/skills/controller/references/permission-sync-templates.md +152 -0
- package/templates/skills/controller/steps/step-03-generate.md +166 -158
- package/templates/skills/controller/steps/step-04-perms.md +5 -144
- package/templates/skills/controller/templates.md +11 -2
- package/templates/skills/debug/SKILL.md +7 -0
- package/templates/skills/explore/SKILL.md +6 -0
- package/templates/skills/feature-full/SKILL.md +39 -142
- package/templates/skills/feature-full/steps/step-01-implementation.md +120 -0
- package/templates/skills/gitflow/references/init-config-template.md +135 -0
- package/templates/skills/gitflow/references/init-name-normalization.md +103 -0
- package/templates/skills/gitflow/references/plan-template.md +69 -0
- package/templates/skills/gitflow/references/start-efcore-preflight.md +70 -0
- package/templates/skills/gitflow/references/start-local-config.md +110 -0
- package/templates/skills/gitflow/steps/step-init.md +18 -289
- package/templates/skills/gitflow/steps/step-plan.md +6 -63
- package/templates/skills/gitflow/steps/step-start.md +16 -126
- package/templates/skills/mcp/SKILL.md +9 -213
- package/templates/skills/mcp/steps/step-01-healthcheck.md +108 -0
- package/templates/skills/mcp/steps/step-02-tools.md +73 -0
- package/templates/skills/notification/SKILL.md +7 -0
- package/templates/skills/quick-search/SKILL.md +5 -0
- package/templates/skills/ralph-loop/SKILL.md +99 -381
- package/templates/skills/ralph-loop/references/category-rules.md +259 -0
- package/templates/skills/ralph-loop/references/compact-loop.md +182 -0
- package/templates/skills/ralph-loop/references/core-seed-data.md +173 -21
- package/templates/skills/ralph-loop/references/task-transform-legacy.md +259 -0
- package/templates/skills/ralph-loop/references/team-orchestration.md +189 -0
- package/templates/skills/ralph-loop/steps/step-00-init.md +111 -383
- package/templates/skills/ralph-loop/steps/step-01-task.md +79 -896
- package/templates/skills/ralph-loop/steps/step-02-execute.md +68 -680
- package/templates/skills/ralph-loop/steps/step-03-commit.md +47 -277
- package/templates/skills/ralph-loop/steps/step-04-check.md +124 -607
- package/templates/skills/ralph-loop/steps/step-05-report.md +68 -367
- package/templates/skills/refactor/SKILL.md +12 -176
- package/templates/skills/refactor/steps/step-01-discover.md +60 -0
- package/templates/skills/refactor/steps/step-02-execute.md +67 -0
- package/templates/skills/review-code/SKILL.md +19 -257
- package/templates/skills/review-code/steps/step-01-smartstack.md +96 -0
- package/templates/skills/review-code/steps/step-02-detailed-review.md +80 -0
- package/templates/skills/review-code/steps/step-03-react.md +44 -0
- package/templates/skills/ui-components/SKILL.md +7 -0
- package/templates/skills/utils/SKILL.md +6 -0
- package/templates/skills/validate/SKILL.md +6 -0
- package/templates/skills/validate-feature/SKILL.md +8 -0
- package/templates/skills/workflow/SKILL.md +40 -118
- package/templates/skills/workflow/steps/step-01-implementation.md +84 -0
|
@@ -148,79 +148,9 @@ questions:
|
|
|
148
148
|
|
|
149
149
|
#### If User Selects YES:
|
|
150
150
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
**
|
|
154
|
-
|
|
155
|
-
1. **`Infrastructure/Persistence/Seeding/Data/{Domain}/{EntityName}SeedData.cs`**
|
|
156
|
-
|
|
157
|
-
Follow the SmartStack.app pattern (same architecture as core):
|
|
158
|
-
- Static class with `internal static IEnumerable<{EntityName}SeedItem> GetAll{EntityName}s()`
|
|
159
|
-
- Use deterministic GUIDs (NEVER `Guid.NewGuid()`)
|
|
160
|
-
- Include 3-5 sample entities with varied, realistic data
|
|
161
|
-
- Internal record class `{EntityName}SeedItem` with all entity properties
|
|
162
|
-
- For multi-tenant entities: organize by tenant using `GetTenant1{EntityName}s()` helper methods
|
|
163
|
-
- Reference existing tenant/user IDs from `TenantSeedData`/`UserSeedData` for foreign keys
|
|
164
|
-
|
|
165
|
-
```csharp
|
|
166
|
-
// Infrastructure/Persistence/Seeding/Data/{Domain}/{EntityName}SeedData.cs
|
|
167
|
-
|
|
168
|
-
public static class {EntityName}SeedData
|
|
169
|
-
{
|
|
170
|
-
public static readonly Guid Sample1Id = Guid.Parse("...");
|
|
171
|
-
public static readonly Guid Sample2Id = Guid.Parse("...");
|
|
172
|
-
public static readonly Guid Sample3Id = Guid.Parse("...");
|
|
173
|
-
|
|
174
|
-
internal static IEnumerable<{EntityName}SeedItem> GetAll{EntityName}s()
|
|
175
|
-
{
|
|
176
|
-
return new[]
|
|
177
|
-
{
|
|
178
|
-
new {EntityName}SeedItem { Id = Sample1Id, /* ... */ },
|
|
179
|
-
new {EntityName}SeedItem { Id = Sample2Id, /* ... */ },
|
|
180
|
-
new {EntityName}SeedItem { Id = Sample3Id, /* ... */ }
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
internal class {EntityName}SeedItem
|
|
186
|
-
{
|
|
187
|
-
public Guid Id { get; init; }
|
|
188
|
-
// ... all required entity properties
|
|
189
|
-
}
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
2. **Update `Infrastructure/Persistence/Seeding/DevDataSeeder.cs`**
|
|
193
|
-
- Add `using` for the new SeedData namespace
|
|
194
|
-
- Add `await Seed{EntityName}sAsync(cancellationToken);` in `SeedAsync()` method
|
|
195
|
-
- Add private seeding method:
|
|
196
|
-
|
|
197
|
-
```csharp
|
|
198
|
-
private async Task Seed{EntityName}sAsync(CancellationToken cancellationToken)
|
|
199
|
-
{
|
|
200
|
-
_logger.LogInformation("Seeding demo {EntityName}s...");
|
|
201
|
-
|
|
202
|
-
var existingCount = await _context.{EntityName}s.CountAsync(cancellationToken);
|
|
203
|
-
if (existingCount > 0)
|
|
204
|
-
{
|
|
205
|
-
_logger.LogWarning("{EntityName}s already seeded ({Count} exist), skipping.", existingCount);
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
var createdCount = 0;
|
|
210
|
-
foreach (var seedItem in {EntityName}SeedData.GetAll{EntityName}s())
|
|
211
|
-
{
|
|
212
|
-
var entity = {EntityName}.Create(/* map seedItem properties */);
|
|
213
|
-
typeof({EntityName}).GetProperty("Id")?.SetValue(entity, seedItem.Id);
|
|
214
|
-
_context.{EntityName}s.Add(entity);
|
|
215
|
-
createdCount++;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
if (createdCount > 0)
|
|
219
|
-
await _context.SaveChangesAsync(cancellationToken);
|
|
220
|
-
|
|
221
|
-
_logger.LogInformation("Created {Count} demo {EntityName}s.", createdCount);
|
|
222
|
-
}
|
|
223
|
-
```
|
|
151
|
+
See [references/backend-entity-seeding.md](../references/backend-entity-seeding.md) for the full seeding pattern:
|
|
152
|
+
1. **SeedData file** (`{EntityName}SeedData.cs`) — static class with deterministic GUIDs, 3-5 samples
|
|
153
|
+
2. **DevDataSeeder update** — add `Seed{EntityName}sAsync()` method with idempotent check
|
|
224
154
|
|
|
225
155
|
#### If User Selects NO:
|
|
226
156
|
|
|
@@ -246,58 +176,10 @@ Store entity information for frontend generation:
|
|
|
246
176
|
|
|
247
177
|
## CONTROLLER NAVROUTE AND FOLDER HIERARCHY
|
|
248
178
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
```
|
|
254
|
-
Api/Controllers/
|
|
255
|
-
├── Admin/ ← platform.administration
|
|
256
|
-
│ ├── {Application}/ ← Application sub-folder (e.g., AI/, Communications/, Tenants/)
|
|
257
|
-
│ │ └── {EntityName}Controller.cs
|
|
258
|
-
│ └── {EntityName}Controller.cs ← Direct controllers (no application sub-folder)
|
|
259
|
-
├── Business/ ← business.*
|
|
260
|
-
│ └── {EntityName}Controller.cs
|
|
261
|
-
├── Support/ ← platform.support
|
|
262
|
-
│ └── {EntityName}Controller.cs
|
|
263
|
-
├── User/ ← personal.*
|
|
264
|
-
│ └── {EntityName}Controller.cs
|
|
265
|
-
└── {SharedControllers}.cs ← Root-level (Auth, Config, Navigation, etc.)
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
### Context-to-Folder Mapping
|
|
269
|
-
|
|
270
|
-
| NavRoute Context | Controller Folder | Example |
|
|
271
|
-
|-----------------|-------------------|---------|
|
|
272
|
-
| `platform.administration` | `Admin` | `Controllers/Admin/TenantsController.cs` |
|
|
273
|
-
| `platform.administration.{app}` | `Admin/{App}` | `Controllers/Admin/AI/AiPromptsController.cs` |
|
|
274
|
-
| `platform.support` | `Support` | `Controllers/Support/TicketsController.cs` |
|
|
275
|
-
| `business.*` | `Business` | `Controllers/Business/MyTicketsController.cs` |
|
|
276
|
-
| `personal.*` | `User` | `Controllers/User/PreferencesController.cs` |
|
|
277
|
-
|
|
278
|
-
### Controller Attributes
|
|
279
|
-
|
|
280
|
-
The generated controller uses NavRoute attribute:
|
|
281
|
-
|
|
282
|
-
```csharp
|
|
283
|
-
[NavRoute("{full_path}")]
|
|
284
|
-
[ApiController]
|
|
285
|
-
[Authorize]
|
|
286
|
-
public class {EntityName}Controller : ControllerBase
|
|
287
|
-
{
|
|
288
|
-
[HttpGet]
|
|
289
|
-
[RequirePermission(Permissions.{Context}.{Application}.{Module}.Read)]
|
|
290
|
-
public async Task<ActionResult<IEnumerable<{EntityName}Dto>>> GetAll() { ... }
|
|
291
|
-
|
|
292
|
-
// ... other CRUD methods
|
|
293
|
-
}
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
This ensures:
|
|
297
|
-
- API route is derived from navigation path
|
|
298
|
-
- Permissions use the constants from Permissions.cs
|
|
299
|
-
- Frontend can discover API path from NavRoute registry
|
|
300
|
-
- Controller file is in the correct context/application folder
|
|
179
|
+
See [references/backend-controller-hierarchy.md](../references/backend-controller-hierarchy.md) for the complete reference:
|
|
180
|
+
- Controller file organization (Admin/Business/Support/User folders)
|
|
181
|
+
- Context-to-folder mapping table
|
|
182
|
+
- NavRoute attribute C# template with RequirePermission
|
|
301
183
|
|
|
302
184
|
---
|
|
303
185
|
|
|
@@ -323,234 +205,22 @@ If MCP call fails:
|
|
|
323
205
|
|
|
324
206
|
## POST-GENERATION VERIFICATION (MANDATORY)
|
|
325
207
|
|
|
326
|
-
**Before proceeding to step-05, run
|
|
327
|
-
|
|
328
|
-
### Check 1: Backend Build (BLOCKING)
|
|
329
|
-
|
|
330
|
-
```bash
|
|
331
|
-
dotnet build {SolutionName}.sln --no-restore
|
|
332
|
-
```
|
|
333
|
-
|
|
334
|
-
IF build fails:
|
|
335
|
-
- Read the error output carefully
|
|
336
|
-
- Fix compilation errors in generated files (common: missing `using`, wrong namespace, type mismatch)
|
|
337
|
-
- Re-run build until it succeeds
|
|
338
|
-
- DO NOT proceed to step-05 until the backend builds successfully
|
|
339
|
-
|
|
340
|
-
### Check 2: DbSet Registration (BLOCKING)
|
|
341
|
-
|
|
342
|
-
Verify the entity DbSet is registered in the DbContext interface:
|
|
343
|
-
|
|
344
|
-
```
|
|
345
|
-
Search for: DbSet<{EntityName}>
|
|
346
|
-
In: **/I{DbContextName}.cs or **/{DbContextName}.cs
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
IF NOT found: Add the DbSet declaration immediately:
|
|
350
|
-
```csharp
|
|
351
|
-
public DbSet<{EntityName}> {EntityName}s => Set<{EntityName}>();
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
### Check 3: DI Registration (BLOCKING)
|
|
208
|
+
**Before proceeding to step-05, run ALL checks.**
|
|
355
209
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
```
|
|
359
|
-
Search for: I{EntityName}Service
|
|
360
|
-
In: **/DependencyInjection.cs
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
IF NOT found: Add the service registration immediately:
|
|
364
|
-
```csharp
|
|
365
|
-
services.AddScoped<I{EntityName}Service, {EntityName}Service>();
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
### Check 4: RequirePermission Attributes (BLOCKING)
|
|
369
|
-
|
|
370
|
-
Verify ALL controller actions have `[RequirePermission]` attributes:
|
|
371
|
-
|
|
372
|
-
```
|
|
373
|
-
Search for: [HttpGet], [HttpPost], [HttpPut], [HttpDelete]
|
|
374
|
-
In: **/Controllers/**/{EntityName}Controller.cs
|
|
375
|
-
```
|
|
376
|
-
|
|
377
|
-
Each HTTP action MUST have a corresponding `[RequirePermission(Permissions.{Context}.{Application}.{Module}.{Action})]`.
|
|
378
|
-
IF any action is missing the attribute: Add it immediately.
|
|
379
|
-
|
|
380
|
-
### Check 5: Entity Configuration (BLOCKING)
|
|
381
|
-
|
|
382
|
-
Verify the EF Core configuration file exists and has correct structure:
|
|
383
|
-
|
|
384
|
-
```
|
|
385
|
-
Search for: {EntityName}Configuration
|
|
386
|
-
In: **/Persistence/Configurations/**/*Configuration.cs
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
Verify:
|
|
390
|
-
- `builder.ToTable("{table_prefix}{EntityName}s")` uses the correct table prefix
|
|
391
|
-
- `builder.HasKey(e => e.Id)` is present
|
|
392
|
-
- `builder.HasIndex` is defined for unique fields (e.g., Code)
|
|
393
|
-
|
|
394
|
-
IF configuration is incomplete: Fix it before continuing.
|
|
395
|
-
|
|
396
|
-
### Check 5b: Seeding Infrastructure (BLOCKING - first entity only)
|
|
397
|
-
|
|
398
|
-
**If this is the FIRST entity created in this project (no existing DevDataSeeder):**
|
|
399
|
-
|
|
400
|
-
Scaffold the full seeding infrastructure following the SmartStack.app architecture:
|
|
401
|
-
|
|
402
|
-
1. **Create `Infrastructure/Persistence/Seeding/Data/SeedConstants.cs`**
|
|
403
|
-
|
|
404
|
-
```csharp
|
|
405
|
-
namespace {BaseNamespace}.Infrastructure.Persistence.Seeding.Data;
|
|
406
|
-
|
|
407
|
-
/// <summary>
|
|
408
|
-
/// Shared constants for seed data across all modules.
|
|
409
|
-
/// </summary>
|
|
410
|
-
public static class SeedConstants
|
|
411
|
-
{
|
|
412
|
-
public static readonly DateTime SeedDate = new(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
|
413
|
-
}
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
2. **Create `Infrastructure/Persistence/Seeding/DevDataSeeder.cs`**
|
|
417
|
-
|
|
418
|
-
```csharp
|
|
419
|
-
using Microsoft.EntityFrameworkCore;
|
|
420
|
-
using Microsoft.Extensions.Logging;
|
|
421
|
-
using SmartStack.Application.Common.Interfaces;
|
|
422
|
-
|
|
423
|
-
namespace {BaseNamespace}.Infrastructure.Persistence.Seeding;
|
|
424
|
-
|
|
425
|
-
/// <summary>
|
|
426
|
-
/// Seeds development/demo data at application startup.
|
|
427
|
-
/// Only runs when EnableDevSeeding = true.
|
|
428
|
-
/// </summary>
|
|
429
|
-
public class DevDataSeeder : IDevDataSeeder
|
|
430
|
-
{
|
|
431
|
-
private readonly ExtensionsDbContext _context;
|
|
432
|
-
private readonly ILogger<DevDataSeeder> _logger;
|
|
433
|
-
|
|
434
|
-
public DevDataSeeder(ExtensionsDbContext context, ILogger<DevDataSeeder> logger)
|
|
435
|
-
{
|
|
436
|
-
_context = context;
|
|
437
|
-
_logger = logger;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
public async Task SeedAsync(CancellationToken cancellationToken = default)
|
|
441
|
-
{
|
|
442
|
-
_logger.LogInformation("Starting development data seeding...");
|
|
443
|
-
// Add Seed{Entity}sAsync calls here as entities are created
|
|
444
|
-
_logger.LogInformation("Development data seeding complete.");
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
```
|
|
448
|
-
|
|
449
|
-
3. **Register DevDataSeeder in `Infrastructure/DependencyInjection.cs`:**
|
|
450
|
-
```csharp
|
|
451
|
-
services.AddScoped<IDevDataSeeder, DevDataSeeder>();
|
|
452
|
-
```
|
|
453
|
-
|
|
454
|
-
**If DevDataSeeder already exists:** Skip this check.
|
|
455
|
-
|
|
456
|
-
### Check 5c: SqlObjects Directory (BLOCKING - first entity only)
|
|
457
|
-
|
|
458
|
-
**If this is the FIRST entity in the project (no existing SqlObjectHelper):**
|
|
459
|
-
|
|
460
|
-
Scaffold the SQL objects infrastructure:
|
|
461
|
-
|
|
462
|
-
1. **Create `Infrastructure/Persistence/SqlObjects/SqlObjectHelper.cs`**
|
|
463
|
-
|
|
464
|
-
```csharp
|
|
465
|
-
using System.Reflection;
|
|
466
|
-
using Microsoft.EntityFrameworkCore.Migrations;
|
|
467
|
-
|
|
468
|
-
namespace {BaseNamespace}.Infrastructure.Persistence.SqlObjects;
|
|
469
|
-
|
|
470
|
-
/// <summary>
|
|
471
|
-
/// Helper for applying SQL objects (Functions, Views, Stored Procedures) from embedded resources.
|
|
472
|
-
/// SQL files use CREATE OR ALTER for idempotency — safe to re-run on any migration or squash.
|
|
473
|
-
/// </summary>
|
|
474
|
-
public static class SqlObjectHelper
|
|
475
|
-
{
|
|
476
|
-
private static readonly Assembly Assembly = typeof(SqlObjectHelper).Assembly;
|
|
477
|
-
private const string ResourcePrefix = "{BaseNamespace}.Infrastructure.Persistence.SqlObjects.";
|
|
478
|
-
|
|
479
|
-
public static void ApplyAll(MigrationBuilder migrationBuilder)
|
|
480
|
-
{
|
|
481
|
-
ApplyAllFunctions(migrationBuilder);
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
public static void ApplyAllFunctions(MigrationBuilder migrationBuilder)
|
|
485
|
-
{
|
|
486
|
-
ApplyCategory(migrationBuilder, "Functions");
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
public static void ApplyOne(MigrationBuilder migrationBuilder, string resourceName)
|
|
490
|
-
{
|
|
491
|
-
var sql = ReadSqlObject(resourceName);
|
|
492
|
-
migrationBuilder.Sql(sql);
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
public static string ReadSqlObject(string resourceName)
|
|
496
|
-
{
|
|
497
|
-
var fullName = ResourcePrefix + resourceName;
|
|
498
|
-
using var stream = Assembly.GetManifestResourceStream(fullName)
|
|
499
|
-
?? throw new InvalidOperationException(
|
|
500
|
-
$"SQL object resource '{fullName}' not found. " +
|
|
501
|
-
$"Ensure the .sql file is marked as EmbeddedResource in the .csproj.");
|
|
502
|
-
using var reader = new StreamReader(stream);
|
|
503
|
-
return reader.ReadToEnd();
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
private static void ApplyCategory(MigrationBuilder migrationBuilder, string category)
|
|
507
|
-
{
|
|
508
|
-
var prefix = ResourcePrefix + category + ".";
|
|
509
|
-
var resources = Assembly.GetManifestResourceNames()
|
|
510
|
-
.Where(n => n.StartsWith(prefix, StringComparison.Ordinal)
|
|
511
|
-
&& n.EndsWith(".sql", StringComparison.Ordinal))
|
|
512
|
-
.OrderBy(n => n, StringComparer.Ordinal);
|
|
513
|
-
|
|
514
|
-
foreach (var resource in resources)
|
|
515
|
-
{
|
|
516
|
-
using var stream = Assembly.GetManifestResourceStream(resource)!;
|
|
517
|
-
using var reader = new StreamReader(stream);
|
|
518
|
-
migrationBuilder.Sql(reader.ReadToEnd());
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
```
|
|
523
|
-
|
|
524
|
-
2. **Create empty directory `Infrastructure/Persistence/SqlObjects/Functions/`**
|
|
525
|
-
- Where `.sql` files for TVFs and scalar functions will be stored
|
|
526
|
-
|
|
527
|
-
3. **Ensure `.csproj` has EmbeddedResource glob for SQL files:**
|
|
528
|
-
```xml
|
|
529
|
-
<ItemGroup>
|
|
530
|
-
<EmbeddedResource Include="Persistence\SqlObjects\**\*.sql" />
|
|
531
|
-
</ItemGroup>
|
|
532
|
-
```
|
|
533
|
-
|
|
534
|
-
**If SqlObjectHelper already exists:** Skip this check.
|
|
535
|
-
|
|
536
|
-
### Check 6: Convention Validation (RECOMMENDED)
|
|
537
|
-
|
|
538
|
-
Run MCP convention validation on the generated backend code:
|
|
539
|
-
|
|
540
|
-
```
|
|
541
|
-
Tool: mcp__smartstack__validate_conventions
|
|
542
|
-
Args:
|
|
543
|
-
target: "backend"
|
|
544
|
-
scope: "{entity_name}"
|
|
545
|
-
```
|
|
210
|
+
See [references/backend-verification.md](../references/backend-verification.md) for the complete verification checklist:
|
|
546
211
|
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
212
|
+
| Check | Type | What |
|
|
213
|
+
|-------|------|------|
|
|
214
|
+
| 1. Backend Build | BLOCKING | `dotnet build --no-restore` must succeed |
|
|
215
|
+
| 2. DbSet Registration | BLOCKING | `DbSet<{EntityName}>` in DbContext |
|
|
216
|
+
| 3. DI Registration | BLOCKING | `I{EntityName}Service` in DependencyInjection.cs |
|
|
217
|
+
| 4. RequirePermission | BLOCKING | All HTTP actions have `[RequirePermission]` |
|
|
218
|
+
| 5. Entity Configuration | BLOCKING | Table prefix, HasKey, HasIndex |
|
|
219
|
+
| 5b. Seeding Infrastructure | BLOCKING (first entity) | SeedConstants + DevDataSeeder + DI |
|
|
220
|
+
| 5c. SqlObjects Directory | BLOCKING (first entity) | SqlObjectHelper + Functions/ + .csproj EmbeddedResource |
|
|
221
|
+
| 6. Convention Validation | RECOMMENDED | `mcp__smartstack__validate_conventions` |
|
|
552
222
|
|
|
553
|
-
IF
|
|
223
|
+
IF any BLOCKING check fails: Fix before proceeding to step-05.
|
|
554
224
|
|
|
555
225
|
---
|
|
556
226
|
|
|
@@ -192,38 +192,9 @@ If the generated translations need customization (e.g., replacing generic title
|
|
|
192
192
|
|
|
193
193
|
## ROUTING RULES
|
|
194
194
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
**
|
|
198
|
-
|
|
199
|
-
```tsx
|
|
200
|
-
// ✅ CORRECT - Inside BusinessLayout (shell renders: header + AvatarMenu + sidebar)
|
|
201
|
-
<Route path="/business" element={<BusinessLayout />}>
|
|
202
|
-
<Route path="sales/products" element={<ProductsPage />} />
|
|
203
|
-
</Route>
|
|
204
|
-
|
|
205
|
-
// ❌ FORBIDDEN - Outside layout (NO shell, NO header, NO AvatarMenu!)
|
|
206
|
-
<Route path="/business/sales/products" element={<ProductsPage />} />
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
### Rule 2: Use nested routes (not flat)
|
|
210
|
-
|
|
211
|
-
**CRITICAL:** SmartStack requires NESTED routes within the layout:
|
|
212
|
-
|
|
213
|
-
```tsx
|
|
214
|
-
// ✅ CORRECT - Nested routes inside layout
|
|
215
|
-
<Route path="/business" element={<BusinessLayout />}>
|
|
216
|
-
<Route path="sales">
|
|
217
|
-
<Route index element={<Navigate to="products" replace />} />
|
|
218
|
-
<Route path="products" element={<ProductsPage />} />
|
|
219
|
-
<Route path="orders" element={<OrdersPage />} />
|
|
220
|
-
</Route>
|
|
221
|
-
</Route>
|
|
222
|
-
|
|
223
|
-
// ❌ FORBIDDEN - Flat routes (cause redirect issues + bypass layout)
|
|
224
|
-
<Route path="/business/sales" element={<Navigate to="products" />} />
|
|
225
|
-
<Route path="/business/sales/products" element={<ProductsPage />} />
|
|
226
|
-
```
|
|
195
|
+
See [references/frontend-verification.md](../references/frontend-verification.md) for detailed routing rules with code examples:
|
|
196
|
+
- **Rule 1:** Routes MUST be inside Layout wrappers (BusinessLayout, AdminLayout, UserLayout)
|
|
197
|
+
- **Rule 2:** Use NESTED routes (not flat) — flat routes bypass layout and break the shell
|
|
227
198
|
|
|
228
199
|
---
|
|
229
200
|
|
|
@@ -247,76 +218,16 @@ locales/
|
|
|
247
218
|
|
|
248
219
|
## POST-GENERATION VERIFICATION (MANDATORY)
|
|
249
220
|
|
|
250
|
-
**Before proceeding to step-06, run
|
|
251
|
-
|
|
252
|
-
### 1. CSS Variables Check (BLOCKING)
|
|
253
|
-
|
|
254
|
-
Scan all generated `.tsx` files for hardcoded Tailwind colors:
|
|
255
|
-
|
|
256
|
-
```
|
|
257
|
-
FORBIDDEN patterns: bg-blue-, bg-red-, bg-green-, bg-gray-, bg-amber-,
|
|
258
|
-
text-blue-, text-red-, text-green-, text-gray-, text-amber-,
|
|
259
|
-
border-blue-, border-red-, border-green-, border-gray-
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
If ANY hardcoded color is found → **FIX IT** using CSS variables from style-guide.md before continuing.
|
|
221
|
+
**Before proceeding to step-06, run all 7 checks on generated frontend files.**
|
|
263
222
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
If a grid/card view is generated, verify it uses `EntityCard` component (not custom divs).
|
|
273
|
-
|
|
274
|
-
### 4. i18n Check (BLOCKING)
|
|
275
|
-
|
|
276
|
-
Verify exactly **4 language files** exist with identical key structures:
|
|
277
|
-
- `fr/{entityCode}.json`
|
|
278
|
-
- `en/{entityCode}.json`
|
|
279
|
-
- `it/{entityCode}.json`
|
|
280
|
-
- `de/{entityCode}.json`
|
|
281
|
-
|
|
282
|
-
### 5. Route Check (BLOCKING)
|
|
283
|
-
|
|
284
|
-
Verify routes are:
|
|
285
|
-
- **INSIDE** the Layout wrapper (`BusinessLayout`, `AdminLayout`, or `UserLayout`)
|
|
286
|
-
- **NESTED** (not flat)
|
|
287
|
-
- Following path convention: `/{context}/{application}/{module}`
|
|
288
|
-
|
|
289
|
-
### 6. States Check
|
|
290
|
-
|
|
291
|
-
Verify the list page includes:
|
|
292
|
-
- Loading state (spinner)
|
|
293
|
-
- Error state (icon + message + retry button)
|
|
294
|
-
- Empty state (icon + message)
|
|
295
|
-
|
|
296
|
-
### 7. TypeScript Build Check (BLOCKING)
|
|
297
|
-
|
|
298
|
-
Run the frontend type check to verify all generated files compile:
|
|
299
|
-
|
|
300
|
-
```bash
|
|
301
|
-
cd web && npx tsc --noEmit 2>&1 | head -50
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
OR if the project uses a build script:
|
|
305
|
-
|
|
306
|
-
```bash
|
|
307
|
-
cd web && npm run build 2>&1 | head -80
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
IF type errors exist **in generated files**: Fix them before proceeding.
|
|
311
|
-
Common issues: missing imports, wrong interface names, incorrect prop types, missing hook return types.
|
|
312
|
-
|
|
313
|
-
IF type errors exist **in other pre-existing files**: NON-BLOCKING. Note them but proceed.
|
|
314
|
-
|
|
315
|
-
**Focus only on errors in files generated by this step:**
|
|
316
|
-
- `pages/{context}/{application}/{module}/*.tsx`
|
|
317
|
-
- `services/api/{entityCode}Api.ts`
|
|
318
|
-
- `types/{entityName}.types.ts`
|
|
319
|
-
- `hooks/use{EntityName}*.ts`
|
|
223
|
+
See [references/frontend-verification.md](../references/frontend-verification.md) for the complete checklist:
|
|
224
|
+
1. CSS Variables (BLOCKING) — no hardcoded Tailwind colors
|
|
225
|
+
2. API Client (BLOCKING) — use configured client, not raw axios
|
|
226
|
+
3. EntityCard — use EntityCard component for grid/card views
|
|
227
|
+
4. i18n (BLOCKING) — exactly 4 language files with identical keys
|
|
228
|
+
5. Route (BLOCKING) — inside Layout wrapper, nested, correct path convention
|
|
229
|
+
6. States — loading, error, empty states present
|
|
230
|
+
7. TypeScript Build (BLOCKING) — `npx tsc --noEmit` passes for generated files
|
|
320
231
|
|
|
321
232
|
---
|
|
322
233
|
|
|
@@ -47,78 +47,11 @@ From previous steps:
|
|
|
47
47
|
|
|
48
48
|
## PRE-REQUISITES
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
# Look for existing test project
|
|
56
|
-
ls *Tests*/*.csproj 2>/dev/null || ls tests/*/*.csproj 2>/dev/null
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
If NO test project exists, create one:
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
dotnet new xunit -n {SolutionName}.Tests -o tests/{SolutionName}.Tests
|
|
63
|
-
dotnet sln add tests/{SolutionName}.Tests/{SolutionName}.Tests.csproj
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### 2. Verify Required NuGet Packages
|
|
67
|
-
|
|
68
|
-
The test project MUST have these packages:
|
|
69
|
-
|
|
70
|
-
| Package | Purpose |
|
|
71
|
-
|---------|---------|
|
|
72
|
-
| `xunit` | Test framework |
|
|
73
|
-
| `FluentAssertions` | Assertion library |
|
|
74
|
-
| `Moq` | Mocking framework |
|
|
75
|
-
| `Microsoft.AspNetCore.Mvc.Testing` | Integration test support |
|
|
76
|
-
| `Microsoft.EntityFrameworkCore.Sqlite` | SQLite in-memory for REAL integration tests |
|
|
77
|
-
| `Microsoft.Data.Sqlite` | SQLite connection support |
|
|
78
|
-
| `Microsoft.EntityFrameworkCore.InMemory` | In-memory DB for repository tests |
|
|
79
|
-
| `FluentValidation.TestHelper` | Validator testing support |
|
|
80
|
-
|
|
81
|
-
```bash
|
|
82
|
-
cd tests/{SolutionName}.Tests
|
|
83
|
-
dotnet add package FluentAssertions
|
|
84
|
-
dotnet add package Moq
|
|
85
|
-
dotnet add package Microsoft.AspNetCore.Mvc.Testing
|
|
86
|
-
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
|
|
87
|
-
dotnet add package Microsoft.Data.Sqlite
|
|
88
|
-
dotnet add package Microsoft.EntityFrameworkCore.InMemory
|
|
89
|
-
dotnet add package FluentValidation.TestHelper
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
### 3. Add Project References
|
|
93
|
-
|
|
94
|
-
The test project MUST reference the API project (for WebApplicationFactory):
|
|
95
|
-
|
|
96
|
-
```bash
|
|
97
|
-
cd tests/{SolutionName}.Tests
|
|
98
|
-
dotnet add reference ../../src/{SolutionName}.Api/{SolutionName}.Api.csproj
|
|
99
|
-
dotnet add reference ../../src/{SolutionName}.Application/{SolutionName}.Application.csproj
|
|
100
|
-
dotnet add reference ../../src/{SolutionName}.Domain/{SolutionName}.Domain.csproj
|
|
101
|
-
dotnet add reference ../../src/{SolutionName}.Infrastructure/{SolutionName}.Infrastructure.csproj
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
### 4. Ensure Program.cs is Accessible (BLOCKING)
|
|
105
|
-
|
|
106
|
-
The API project's `Program` class must be accessible for `WebApplicationFactory<Program>`.
|
|
107
|
-
|
|
108
|
-
Check if `Program.cs` ends with `public partial class Program { }`. If not, add it:
|
|
109
|
-
|
|
110
|
-
```csharp
|
|
111
|
-
// At the very end of Program.cs
|
|
112
|
-
public partial class Program { }
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
**Alternatively**, add to the API `.csproj`:
|
|
116
|
-
|
|
117
|
-
```xml
|
|
118
|
-
<ItemGroup>
|
|
119
|
-
<InternalsVisibleTo Include="{SolutionName}.Tests" />
|
|
120
|
-
</ItemGroup>
|
|
121
|
-
```
|
|
50
|
+
See [references/test-prerequisites.md](../references/test-prerequisites.md) for the complete setup:
|
|
51
|
+
1. Verify test project exists (create xunit project if missing)
|
|
52
|
+
2. Install required NuGet packages (xunit, FluentAssertions, Moq, Mvc.Testing, EF Sqlite, etc.)
|
|
53
|
+
3. Add project references (API, Application, Domain, Infrastructure)
|
|
54
|
+
4. Ensure Program.cs is accessible for WebApplicationFactory (BLOCKING)
|
|
122
55
|
|
|
123
56
|
---
|
|
124
57
|
|
|
@@ -343,62 +276,13 @@ dotnet test tests/{SolutionName}.Tests/{SolutionName}.Tests.csproj --no-build --
|
|
|
343
276
|
|
|
344
277
|
## FRONTEND TESTS (React Components)
|
|
345
278
|
|
|
346
|
-
|
|
279
|
+
See [references/test-frontend.md](../references/test-frontend.md) for the complete frontend test setup:
|
|
347
280
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
```
|
|
354
|
-
|
|
355
|
-
If NOT found, deploy the test infrastructure:
|
|
356
|
-
|
|
357
|
-
1. **Install packages:**
|
|
358
|
-
|
|
359
|
-
```bash
|
|
360
|
-
cd {WebProjectPath}
|
|
361
|
-
npm install -D vitest @testing-library/react @testing-library/jest-dom @testing-library/user-event jsdom msw
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
2. **Copy infrastructure files** from SmartStack templates:
|
|
365
|
-
|
|
366
|
-
| Template Source | Destination |
|
|
367
|
-
|----------------|-------------|
|
|
368
|
-
| `templates/project/test-frontend/vitest.config.ts` | `{WebProjectPath}/vitest.config.ts` |
|
|
369
|
-
| `templates/project/test-frontend/setup.ts` | `{WebProjectPath}/src/test/setup.ts` |
|
|
370
|
-
| `templates/project/test-frontend/test-utils.tsx` | `{WebProjectPath}/src/test/test-utils.tsx` |
|
|
371
|
-
| `templates/project/test-frontend/msw/server.ts` | `{WebProjectPath}/src/test/msw/server.ts` |
|
|
372
|
-
| `templates/project/test-frontend/msw/handlers.ts` | `{WebProjectPath}/src/test/msw/handlers.ts` |
|
|
373
|
-
|
|
374
|
-
3. **Add test script** to `package.json` (if missing):
|
|
375
|
-
|
|
376
|
-
```json
|
|
377
|
-
{
|
|
378
|
-
"scripts": {
|
|
379
|
-
"test": "vitest run",
|
|
380
|
-
"test:watch": "vitest",
|
|
381
|
-
"test:coverage": "vitest run --coverage"
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
```
|
|
385
|
-
|
|
386
|
-
### 8. Generate Frontend Tests
|
|
387
|
-
|
|
388
|
-
```
|
|
389
|
-
Tool: mcp__smartstack__scaffold_frontend_tests
|
|
390
|
-
Args:
|
|
391
|
-
name: "{entity_name}"
|
|
392
|
-
components: ["all"]
|
|
393
|
-
apiRoute: "/api/{entity_code}"
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
This generates:
|
|
397
|
-
- `src/pages/{context}/{application}/__tests__/{EntityName}Page.test.tsx` - Page rendering, loading, error states
|
|
398
|
-
- `src/pages/{context}/{application}/__tests__/{EntityName}ListView.test.tsx` - List display, pagination, view toggle
|
|
399
|
-
- `src/pages/{context}/{application}/__tests__/{EntityName}DetailPage.test.tsx` - Detail view, tabs, back navigation
|
|
400
|
-
- `src/hooks/__tests__/use{EntityName}Preferences.test.ts` - Preference get/set
|
|
401
|
-
- `src/services/api/__tests__/{entityName}Api.test.ts` - API client calls with MSW
|
|
281
|
+
### 7-8. Infrastructure & Test Generation
|
|
282
|
+
- Check Vitest + Testing Library + MSW configuration
|
|
283
|
+
- Install packages if missing (`vitest`, `@testing-library/react`, `msw`, etc.)
|
|
284
|
+
- Copy infrastructure templates (vitest.config.ts, setup.ts, test-utils.tsx, MSW handlers)
|
|
285
|
+
- Generate tests via `mcp__smartstack__scaffold_frontend_tests` (Page, ListView, DetailPage, Hooks, API)
|
|
402
286
|
|
|
403
287
|
### 9. Run Frontend Tests (BLOCKING)
|
|
404
288
|
|
|
@@ -407,11 +291,7 @@ cd {WebProjectPath}
|
|
|
407
291
|
npx vitest run --reporter=default
|
|
408
292
|
```
|
|
409
293
|
|
|
410
|
-
**ALL frontend tests MUST pass.**
|
|
411
|
-
1. Read the failure output carefully
|
|
412
|
-
2. Fix the failing tests or the components they test
|
|
413
|
-
3. Re-run until all tests pass
|
|
414
|
-
4. Do NOT proceed to the next step until all tests are green
|
|
294
|
+
**ALL frontend tests MUST pass.** Fix failures before proceeding.
|
|
415
295
|
|
|
416
296
|
---
|
|
417
297
|
|