@atlashub/smartstack-cli 3.8.0 → 3.9.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 (120) hide show
  1. package/dist/index.js +365 -2
  2. package/dist/index.js.map +1 -1
  3. package/package.json +2 -1
  4. package/templates/agents/action.md +1 -0
  5. package/templates/agents/ba-writer.md +33 -0
  6. package/templates/agents/explore-codebase.md +1 -0
  7. package/templates/agents/explore-docs.md +1 -0
  8. package/templates/agents/fix-grammar.md +1 -0
  9. package/templates/agents/snipper.md +1 -0
  10. package/templates/skills/admin/SKILL.md +6 -0
  11. package/templates/skills/ai-prompt/SKILL.md +32 -136
  12. package/templates/skills/ai-prompt/steps/step-01-implementation.md +122 -0
  13. package/templates/skills/apex/SKILL.md +120 -0
  14. package/templates/skills/apex/_shared.md +86 -0
  15. package/templates/skills/apex/references/agent-teams-protocol.md +164 -0
  16. package/templates/skills/apex/references/smartstack-layers.md +173 -0
  17. package/templates/skills/apex/steps/step-00-init.md +156 -0
  18. package/templates/skills/apex/steps/step-01-analyze.md +169 -0
  19. package/templates/skills/apex/steps/step-02-plan.md +160 -0
  20. package/templates/skills/apex/steps/step-03-execute.md +166 -0
  21. package/templates/skills/apex/steps/step-04-validate.md +138 -0
  22. package/templates/skills/apex/steps/step-05-examine.md +124 -0
  23. package/templates/skills/apex/steps/step-06-resolve.md +105 -0
  24. package/templates/skills/apex/steps/step-07-tests.md +130 -0
  25. package/templates/skills/apex/steps/step-08-run-tests.md +115 -0
  26. package/templates/skills/application/SKILL.md +10 -0
  27. package/templates/skills/application/references/backend-controller-hierarchy.md +58 -0
  28. package/templates/skills/application/references/backend-entity-seeding.md +72 -0
  29. package/templates/skills/application/references/backend-verification.md +88 -0
  30. package/templates/skills/application/references/frontend-verification.md +111 -0
  31. package/templates/skills/application/references/nav-fallback-procedure.md +200 -0
  32. package/templates/skills/application/references/provider-template.md +134 -0
  33. package/templates/skills/application/references/test-frontend.md +73 -0
  34. package/templates/skills/application/references/test-prerequisites.md +72 -0
  35. package/templates/skills/application/steps/step-01-navigation.md +7 -198
  36. package/templates/skills/application/steps/step-03b-provider.md +4 -128
  37. package/templates/skills/application/steps/step-04-backend.md +20 -350
  38. package/templates/skills/application/steps/step-05-frontend.md +12 -101
  39. package/templates/skills/application/steps/step-07-tests.md +12 -132
  40. package/templates/skills/business-analyse/SKILL.md +11 -2
  41. package/templates/skills/business-analyse/html/ba-interactive.html +176 -14
  42. package/templates/skills/business-analyse/html/src/scripts/01-data-init.js +1 -0
  43. package/templates/skills/business-analyse/html/src/scripts/05-render-specs.js +16 -4
  44. package/templates/skills/business-analyse/html/src/scripts/06-render-consolidation.js +7 -2
  45. package/templates/skills/business-analyse/html/src/scripts/09-export.js +103 -0
  46. package/templates/skills/business-analyse/html/src/scripts/10-comments.js +12 -6
  47. package/templates/skills/business-analyse/html/src/scripts/11-review-panel.js +24 -2
  48. package/templates/skills/business-analyse/html/src/styles/08-review-panel.css +12 -0
  49. package/templates/skills/business-analyse/html/src/template.html +1 -0
  50. package/templates/skills/business-analyse/references/cadrage-structure-cards.md +78 -0
  51. package/templates/skills/business-analyse/references/cadrage-vibe-coding.md +97 -0
  52. package/templates/skills/business-analyse/references/consolidation-structural-checks.md +92 -0
  53. package/templates/skills/business-analyse/references/deploy-data-build.md +121 -0
  54. package/templates/skills/business-analyse/references/deploy-modes.md +49 -0
  55. package/templates/skills/business-analyse/references/handoff-file-templates.md +119 -0
  56. package/templates/skills/business-analyse/references/handoff-mappings.md +81 -0
  57. package/templates/skills/business-analyse/references/html-data-mapping.md +10 -2
  58. package/templates/skills/business-analyse/references/init-schema-deployment.md +65 -0
  59. package/templates/skills/business-analyse/references/review-data-mapping.md +363 -0
  60. package/templates/skills/business-analyse/references/spec-auto-inference.md +57 -0
  61. package/templates/skills/business-analyse/references/ui-dashboard-spec.md +85 -0
  62. package/templates/skills/business-analyse/references/ui-resource-cards.md +110 -0
  63. package/templates/skills/business-analyse/references/validate-incremental-html.md +55 -0
  64. package/templates/skills/business-analyse/steps/step-00-init.md +35 -68
  65. package/templates/skills/business-analyse/steps/step-01-cadrage.md +5 -194
  66. package/templates/skills/business-analyse/steps/step-03a-data.md +6 -49
  67. package/templates/skills/business-analyse/steps/step-03b-ui.md +12 -178
  68. package/templates/skills/business-analyse/steps/step-03d-validate.md +3 -48
  69. package/templates/skills/business-analyse/steps/step-04-consolidation.md +9 -104
  70. package/templates/skills/business-analyse/steps/step-05a-handoff.md +25 -441
  71. package/templates/skills/business-analyse/steps/step-05b-deploy.md +19 -187
  72. package/templates/skills/business-analyse/steps/step-06-review.md +277 -0
  73. package/templates/skills/cc-agent/references/agent-behavior-patterns.md +95 -0
  74. package/templates/skills/cc-agent/steps/step-02-generate.md +5 -78
  75. package/templates/skills/check-version/SKILL.md +7 -0
  76. package/templates/skills/controller/references/controller-code-templates.md +159 -0
  77. package/templates/skills/controller/references/permission-sync-templates.md +152 -0
  78. package/templates/skills/controller/steps/step-03-generate.md +6 -158
  79. package/templates/skills/controller/steps/step-04-perms.md +5 -144
  80. package/templates/skills/debug/SKILL.md +7 -0
  81. package/templates/skills/explore/SKILL.md +6 -0
  82. package/templates/skills/feature-full/SKILL.md +39 -142
  83. package/templates/skills/feature-full/steps/step-01-implementation.md +120 -0
  84. package/templates/skills/gitflow/references/init-config-template.md +135 -0
  85. package/templates/skills/gitflow/references/init-name-normalization.md +103 -0
  86. package/templates/skills/gitflow/references/plan-template.md +69 -0
  87. package/templates/skills/gitflow/references/start-efcore-preflight.md +70 -0
  88. package/templates/skills/gitflow/references/start-local-config.md +110 -0
  89. package/templates/skills/gitflow/steps/step-init.md +18 -289
  90. package/templates/skills/gitflow/steps/step-plan.md +6 -63
  91. package/templates/skills/gitflow/steps/step-start.md +16 -126
  92. package/templates/skills/mcp/SKILL.md +9 -213
  93. package/templates/skills/mcp/steps/step-01-healthcheck.md +108 -0
  94. package/templates/skills/mcp/steps/step-02-tools.md +73 -0
  95. package/templates/skills/notification/SKILL.md +7 -0
  96. package/templates/skills/quick-search/SKILL.md +5 -0
  97. package/templates/skills/ralph-loop/SKILL.md +99 -381
  98. package/templates/skills/ralph-loop/references/category-rules.md +259 -0
  99. package/templates/skills/ralph-loop/references/compact-loop.md +182 -0
  100. package/templates/skills/ralph-loop/references/task-transform-legacy.md +259 -0
  101. package/templates/skills/ralph-loop/references/team-orchestration.md +189 -0
  102. package/templates/skills/ralph-loop/steps/step-00-init.md +111 -383
  103. package/templates/skills/ralph-loop/steps/step-01-task.md +79 -896
  104. package/templates/skills/ralph-loop/steps/step-02-execute.md +68 -680
  105. package/templates/skills/ralph-loop/steps/step-03-commit.md +47 -277
  106. package/templates/skills/ralph-loop/steps/step-04-check.md +124 -607
  107. package/templates/skills/ralph-loop/steps/step-05-report.md +68 -367
  108. package/templates/skills/refactor/SKILL.md +12 -176
  109. package/templates/skills/refactor/steps/step-01-discover.md +60 -0
  110. package/templates/skills/refactor/steps/step-02-execute.md +67 -0
  111. package/templates/skills/review-code/SKILL.md +19 -257
  112. package/templates/skills/review-code/steps/step-01-smartstack.md +96 -0
  113. package/templates/skills/review-code/steps/step-02-detailed-review.md +80 -0
  114. package/templates/skills/review-code/steps/step-03-react.md +44 -0
  115. package/templates/skills/ui-components/SKILL.md +7 -0
  116. package/templates/skills/utils/SKILL.md +6 -0
  117. package/templates/skills/validate/SKILL.md +6 -0
  118. package/templates/skills/validate-feature/SKILL.md +8 -0
  119. package/templates/skills/workflow/SKILL.md +40 -118
  120. package/templates/skills/workflow/steps/step-01-implementation.md +84 -0
@@ -49,134 +49,10 @@ From previous steps:
49
49
 
50
50
  ## FILES TO GENERATE
51
51
 
52
- ### 1. The Provider Class
53
-
54
- **Location:** `Infrastructure/Persistence/Seeding/{AppPascalName}SeedDataProvider.cs`
55
-
56
- Where `{AppPascalName}` is derived from the application code (e.g., `free-bike` -> `FreeBike`).
57
-
58
- **Pattern:**
59
-
60
- ```csharp
61
- using Microsoft.EntityFrameworkCore;
62
- using SmartStack.Application.Common.Interfaces;
63
- using SmartStack.Domain.Navigation;
64
- using SmartStack.Domain.Platform.Administration.Roles;
65
-
66
- namespace {BaseNamespace}.Infrastructure.Persistence.Seeding;
67
-
68
- /// <summary>
69
- /// Seeds {AppLabel} navigation, permissions, and role-permission data
70
- /// into the SmartStack Core schema at application startup.
71
- /// Implements <see cref="IClientSeedDataProvider"/> for runtime seeding
72
- /// (no Core migrations required).
73
- /// </summary>
74
- public class {AppPascalName}SeedDataProvider : IClientSeedDataProvider
75
- {
76
- public int Order => 100;
77
-
78
- public async Task SeedNavigationAsync(ICoreDbContext context, CancellationToken ct)
79
- {
80
- // Check idempotence
81
- var exists = await context.NavigationApplications
82
- .AnyAsync(a => a.Code == "{app_code}", ct);
83
- if (exists) return;
84
-
85
- // 1. Retrieve the parent context ("business", "platform", etc.)
86
- var parentContext = await context.NavigationContexts
87
- .FirstAsync(c => c.Code == "{context_code}", ct);
88
-
89
- // 2. Create the application
90
- var app = NavigationApplication.Create(
91
- parentContext.Id,
92
- "{app_code}",
93
- "{app_label_en}",
94
- "{app_desc_en}",
95
- "{app_icon}",
96
- IconType.Lucide,
97
- "/{context_code}/{app_code}",
98
- {display_order});
99
- context.NavigationApplications.Add(app);
100
- await ((DbContext)context).SaveChangesAsync(ct);
101
-
102
- // 3. Create modules
103
- // Use GUIDs and data from {Module}NavigationSeedData.cs
104
- foreach (var moduleData in GetModuleSeedEntries(app.Id))
105
- {
106
- var module = NavigationModule.Create(
107
- moduleData.ApplicationId,
108
- moduleData.Code,
109
- moduleData.Label,
110
- moduleData.Description,
111
- moduleData.Icon,
112
- IconType.Lucide,
113
- moduleData.Route,
114
- moduleData.DisplayOrder);
115
- context.NavigationModules.Add(module);
116
- }
117
- await ((DbContext)context).SaveChangesAsync(ct);
118
-
119
- // 4. Create translations (4 languages per entity)
120
- // Use data from {Module}NavigationTranslationSeedData.cs
121
- // ...
122
- await ((DbContext)context).SaveChangesAsync(ct);
123
- }
124
-
125
- public async Task SeedPermissionsAsync(ICoreDbContext context, CancellationToken ct)
126
- {
127
- // Check idempotence
128
- var exists = await context.Permissions
129
- .AnyAsync(p => p.Path == "{full_path}.*", ct);
130
- if (exists) return;
131
-
132
- // Retrieve modules by Code for FK resolution
133
- // Use data from {Module}PermissionSeedData.cs
134
- // Create via Permission.CreateForModule(...) and Permission.CreateWildcard(...)
135
- // ...
136
- await ((DbContext)context).SaveChangesAsync(ct);
137
- }
138
-
139
- public async Task SeedRolePermissionsAsync(ICoreDbContext context, CancellationToken ct)
140
- {
141
- // Check idempotence
142
- var exists = await context.RolePermissions
143
- .AnyAsync(rp => rp.Permission!.Path.StartsWith("{full_path}."), ct);
144
- if (exists) return;
145
-
146
- // Retrieve existing roles and created permissions
147
- // Use data from {Module}RolePermissionSeedData.cs
148
- // Create via RolePermission.Create(roleId, permissionId, "system")
149
- // ...
150
- await ((DbContext)context).SaveChangesAsync(ct);
151
- }
152
-
153
- // Private helper methods fed by SeedData classes
154
- // ...
155
- }
156
- ```
157
-
158
- ### 2. DI Registration
159
-
160
- Modify `Infrastructure/DependencyInjection.cs` of the client project:
161
-
162
- ```csharp
163
- // Add using:
164
- using SmartStack.Application.Common.Interfaces;
165
-
166
- // In the registration method:
167
- services.AddScoped<IClientSeedDataProvider, {AppPascalName}SeedDataProvider>();
168
- ```
169
-
170
- ---
171
-
172
- ## CRITICAL RULES
173
-
174
- 1. **Factory methods mandatory**: `NavigationModule.Create(...)`, `Permission.CreateForModule(...)`, `RolePermission.Create(...)` - NEVER `new Entity()`
175
- 2. **Idempotence**: Each Seed method checks existence before inserting
176
- 3. **SaveChangesAsync per group**: Navigation -> save -> Permissions -> save -> RolePermissions -> save
177
- 4. **Deterministic GUIDs**: Use IDs from SeedData classes (not Guid.NewGuid())
178
- 5. **Resolve FK by Code**: Parent modules are found by `Code`, not hardcoded GUID
179
- 6. **Order property**: Use `100` as default. If multiple providers exist, they run in Order sequence
52
+ See [references/provider-template.md](../references/provider-template.md) for the complete implementation:
53
+ - **Provider class** (`{AppPascalName}SeedDataProvider.cs`) with 3 seed methods (Navigation, Permissions, RolePermissions)
54
+ - **DI registration** pattern for `Infrastructure/DependencyInjection.cs`
55
+ - **6 critical rules** (factory methods, idempotence, SaveChangesAsync order, deterministic GUIDs, FK by Code, Order property)
180
56
 
181
57
  ---
182
58
 
@@ -148,79 +148,9 @@ questions:
148
148
 
149
149
  #### If User Selects YES:
150
150
 
151
- **Reference:** See `templates-seed.md` section "TEMPLATE: ENTITY SEED DATA (SeedData Provider)"
152
-
153
- **Generate the following files:**
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
- ### Controller File Location
250
-
251
- Controllers are organized by **context short name** and **application** (matching SmartStack.app pattern):
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 these checks on ALL generated backend files:**
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
- Verify the service is registered in the DI container:
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
- This verifies:
548
- - Naming conventions (PascalCase entities, correct prefixes)
549
- - Architecture layers respected (no cross-layer violations)
550
- - Required attributes present (NavRoute, RequirePermission)
551
- - DTO patterns followed
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 violations found: Fix them before proceeding to step-05.
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
- ### Rule 1: Routes MUST be inside Layout wrappers
196
-
197
- **CRITICAL:** All routes MUST be nested inside the appropriate context layout. This is what provides the SmartStack shell (header with AvatarMenu, sidebar, navigation).
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 these checks on ALL generated frontend files:**
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
- ### 2. API Client Check (BLOCKING)
265
-
266
- Verify all API service files use the configured client:
267
- - **CORRECT:** `import { api } from '@/services/api/apiClient'` or `import api from '../api'`
268
- - **FORBIDDEN:** `import axios from 'axios'`
269
-
270
- ### 3. EntityCard Check
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