@atlashub/smartstack-cli 4.18.0 → 4.19.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 (160) hide show
  1. package/package.json +1 -1
  2. package/templates/agents/ba-reader.md +86 -80
  3. package/templates/agents/ba-writer.md +318 -415
  4. package/templates/agents/docs-context-reader.md +3 -3
  5. package/templates/mcp-scaffolding/frontend/nav-routes.ts.hbs +133 -0
  6. package/templates/mcp-scaffolding/frontend/routes.tsx.hbs +126 -0
  7. package/templates/skills/apex/SKILL.md +29 -16
  8. package/templates/skills/apex/_shared.md +62 -9
  9. package/templates/skills/apex/references/analysis-methods.md +8 -6
  10. package/templates/skills/apex/references/challenge-questions.md +5 -5
  11. package/templates/skills/apex/references/core-seed-data.md +68 -45
  12. package/templates/skills/apex/references/frontend-route-wiring-app-tsx.md +26 -21
  13. package/templates/skills/apex/references/parallel-execution.md +156 -0
  14. package/templates/skills/apex/references/person-extension-pattern.md +12 -12
  15. package/templates/skills/apex/references/post-checks.md +1748 -1726
  16. package/templates/skills/apex/references/smartstack-api.md +63 -57
  17. package/templates/skills/apex/references/smartstack-frontend-compliance.md +594 -0
  18. package/templates/skills/apex/references/smartstack-frontend.md +1246 -1842
  19. package/templates/skills/apex/references/smartstack-layers.md +98 -145
  20. package/templates/skills/apex/steps/step-00-init.md +30 -6
  21. package/templates/skills/apex/steps/step-01-analyze.md +27 -23
  22. package/templates/skills/apex/steps/step-02-plan.md +12 -12
  23. package/templates/skills/apex/steps/step-03-execute.md +198 -143
  24. package/templates/skills/apex/steps/step-04-examine.md +24 -93
  25. package/templates/skills/apex/steps/step-05-deep-review.md +16 -16
  26. package/templates/skills/apex/steps/step-06-resolve.md +9 -9
  27. package/templates/skills/apex/steps/step-07-tests.md +3 -1
  28. package/templates/skills/apex/steps/step-08-run-tests.md +1 -1
  29. package/templates/skills/business-analyse/SKILL.md +182 -301
  30. package/templates/skills/business-analyse/_shared.md +119 -336
  31. package/templates/skills/business-analyse/html/ba-interactive.html +703 -82
  32. package/templates/skills/business-analyse/html/build-html.js +41 -3
  33. package/templates/skills/business-analyse/html/src/partials/cadrage-context.html +34 -0
  34. package/templates/skills/business-analyse/html/src/partials/cadrage-risks.html +48 -0
  35. package/templates/skills/business-analyse/html/src/partials/cadrage-scope.html +49 -0
  36. package/templates/skills/business-analyse/html/src/partials/cadrage-stakeholders.html +55 -0
  37. package/templates/skills/business-analyse/html/src/partials/cadrage-success.html +34 -0
  38. package/templates/skills/business-analyse/html/src/partials/consol-datamodel.html +8 -0
  39. package/templates/skills/business-analyse/html/src/partials/consol-flows.html +29 -0
  40. package/templates/skills/business-analyse/html/src/partials/consol-interactions.html +8 -0
  41. package/templates/skills/business-analyse/html/src/partials/consol-permissions.html +8 -0
  42. package/templates/skills/business-analyse/html/src/partials/decomp-dependencies.html +38 -0
  43. package/templates/skills/business-analyse/html/src/partials/decomp-modules.html +51 -0
  44. package/templates/skills/business-analyse/html/src/partials/handoff-summary.html +24 -0
  45. package/templates/skills/business-analyse/html/src/partials/module-spec-container.html +4 -0
  46. package/templates/skills/business-analyse/html/src/scripts/01-data-init.js +17 -1
  47. package/templates/skills/business-analyse/html/src/scripts/02-navigation.js +31 -5
  48. package/templates/skills/business-analyse/html/src/scripts/05-render-specs.js +100 -63
  49. package/templates/skills/business-analyse/html/src/scripts/06-render-mockups.js +372 -0
  50. package/templates/skills/business-analyse/html/src/scripts/10-comments.js +41 -13
  51. package/templates/skills/business-analyse/html/src/styles/09-mockups-html.css +136 -0
  52. package/templates/skills/business-analyse/patterns/suggestion-catalog.md +7 -5
  53. package/templates/skills/business-analyse/questionnaire/02-stakeholders-scope.md +142 -0
  54. package/templates/skills/business-analyse/questionnaire/03-data-ui.md +94 -0
  55. package/templates/skills/business-analyse/questionnaire/04-risks-metrics.md +150 -0
  56. package/templates/skills/business-analyse/questionnaire/05-cross-module.md +69 -0
  57. package/templates/skills/business-analyse/questionnaire.md +23 -280
  58. package/templates/skills/business-analyse/react/application-viewer.md +2 -2
  59. package/templates/skills/business-analyse/react/components.md +4 -4
  60. package/templates/skills/business-analyse/react/i18n-template.md +1 -1
  61. package/templates/skills/business-analyse/react/schema.md +14 -14
  62. package/templates/skills/business-analyse/references/acceptance-criteria.md +21 -21
  63. package/templates/skills/business-analyse/references/analysis-semantic-checks.md +3 -3
  64. package/templates/skills/business-analyse/references/compilation-structure-cards.md +1 -1
  65. package/templates/skills/business-analyse/references/consolidation-structural-checks.md +5 -5
  66. package/templates/skills/business-analyse/references/deploy-data-build.md +12 -11
  67. package/templates/skills/business-analyse/references/deploy-modes.md +10 -10
  68. package/templates/skills/business-analyse/references/detection-strategies.md +6 -6
  69. package/templates/skills/business-analyse/references/html-data-mapping.md +15 -15
  70. package/templates/skills/business-analyse/references/naming-conventions.md +4 -4
  71. package/templates/skills/business-analyse/references/review-data-mapping.md +29 -29
  72. package/templates/skills/business-analyse/references/robustness-checks.md +36 -36
  73. package/templates/skills/business-analyse/references/spec-auto-inference.md +2 -2
  74. package/templates/skills/business-analyse/references/ui-dashboard-spec.md +1 -1
  75. package/templates/skills/business-analyse/references/ui-resource-cards.md +1 -1
  76. package/templates/skills/business-analyse/references/validation-checklist.md +3 -3
  77. package/templates/skills/business-analyse/references/wireframe-svg-style-guide.md +2 -2
  78. package/templates/skills/business-analyse/schemas/application-schema.json +8 -8
  79. package/templates/skills/business-analyse/schemas/feature-schema.json +3 -3
  80. package/templates/skills/business-analyse/schemas/index-schema.json +47 -0
  81. package/templates/skills/business-analyse/schemas/project-schema.json +6 -6
  82. package/templates/skills/business-analyse/schemas/sections/analysis-schema.json +1 -1
  83. package/templates/skills/business-analyse/schemas/sections/handoff-schema.json +5 -3
  84. package/templates/skills/business-analyse/schemas/sections/metadata-schema.json +4 -4
  85. package/templates/skills/business-analyse/schemas/sections/specification-schema.json +1 -1
  86. package/templates/skills/business-analyse/schemas/shared/common-defs.json +4 -4
  87. package/templates/skills/business-analyse/steps/step-00-init.md +68 -77
  88. package/templates/skills/business-analyse/steps/step-01-cadrage.md +54 -180
  89. package/templates/skills/business-analyse/steps/step-02-structure.md +175 -0
  90. package/templates/skills/business-analyse/steps/step-03-specify.md +198 -0
  91. package/templates/skills/business-analyse/steps/step-04-consolidate.md +478 -0
  92. package/templates/skills/business-analyse/steps/step-05-deploy.md +220 -0
  93. package/templates/skills/business-analyse/steps/step-06-review.md +51 -69
  94. package/templates/skills/business-analyse/templates/tpl-frd.md +1 -1
  95. package/templates/skills/business-analyse/templates/tpl-handoff.md +20 -17
  96. package/templates/skills/business-analyse/templates/tpl-launch-displays.md +2 -2
  97. package/templates/skills/business-analyse/templates-react.md +2 -2
  98. package/templates/skills/derive-prd/SKILL.md +92 -0
  99. package/templates/skills/derive-prd/references/acceptance-criteria.md +169 -0
  100. package/templates/skills/derive-prd/references/entity-domain-mapping.md +115 -0
  101. package/templates/skills/{business-analyse → derive-prd}/references/handoff-file-templates.md +131 -120
  102. package/templates/skills/{business-analyse → derive-prd}/references/handoff-mappings.md +95 -95
  103. package/templates/skills/{business-analyse → derive-prd}/references/handoff-seeddata-generation.md +312 -312
  104. package/templates/skills/{business-analyse → derive-prd}/references/prd-generation.md +262 -263
  105. package/templates/skills/derive-prd/references/readiness-scoring.md +104 -0
  106. package/templates/skills/derive-prd/schemas/handoff-schema.json +95 -0
  107. package/templates/skills/derive-prd/steps/step-00-validate.md +130 -0
  108. package/templates/skills/derive-prd/steps/step-01-transform.md +206 -0
  109. package/templates/skills/derive-prd/steps/step-02-export.md +181 -0
  110. package/templates/skills/{business-analyse → derive-prd}/templates/tpl-progress.md +172 -172
  111. package/templates/skills/ralph-loop/SKILL.md +2 -1
  112. package/templates/skills/ralph-loop/references/init-resume-recovery.md +1 -1
  113. package/templates/skills/ralph-loop/steps/step-01-task.md +2 -2
  114. package/templates/skills/apex/references/agent-teams-protocol.md +0 -203
  115. package/templates/skills/business-analyse/_architecture.md +0 -124
  116. package/templates/skills/business-analyse/_elicitation.md +0 -206
  117. package/templates/skills/business-analyse/_module-loop.md +0 -115
  118. package/templates/skills/business-analyse/_rules.md +0 -142
  119. package/templates/skills/business-analyse/_suggestions.md +0 -34
  120. package/templates/skills/business-analyse/questionnaire/00-application.md +0 -160
  121. package/templates/skills/business-analyse/questionnaire/00b-project.md +0 -85
  122. package/templates/skills/business-analyse/questionnaire/02-stakeholders.md +0 -189
  123. package/templates/skills/business-analyse/questionnaire/03-scope.md +0 -164
  124. package/templates/skills/business-analyse/questionnaire/04-data.md +0 -88
  125. package/templates/skills/business-analyse/questionnaire/05-integrations.md +0 -58
  126. package/templates/skills/business-analyse/questionnaire/06-security.md +0 -68
  127. package/templates/skills/business-analyse/questionnaire/07-ui.md +0 -76
  128. package/templates/skills/business-analyse/questionnaire/08-performance.md +0 -42
  129. package/templates/skills/business-analyse/questionnaire/09-constraints.md +0 -45
  130. package/templates/skills/business-analyse/questionnaire/10-documentation.md +0 -58
  131. package/templates/skills/business-analyse/questionnaire/11-data-lifecycle.md +0 -59
  132. package/templates/skills/business-analyse/questionnaire/12-migration.md +0 -58
  133. package/templates/skills/business-analyse/questionnaire/13-cross-module.md +0 -69
  134. package/templates/skills/business-analyse/questionnaire/14-risk-assumptions.md +0 -135
  135. package/templates/skills/business-analyse/questionnaire/15-success-metrics.md +0 -136
  136. package/templates/skills/business-analyse/references/agent-module-prompt.md +0 -366
  137. package/templates/skills/business-analyse/references/agent-pooling-best-practices.md +0 -557
  138. package/templates/skills/business-analyse/references/cache-warming-strategy.md +0 -566
  139. package/templates/skills/business-analyse/references/cadrage-challenge-patterns.md +0 -41
  140. package/templates/skills/business-analyse/references/cadrage-coverage-matrix.md +0 -74
  141. package/templates/skills/business-analyse/references/cadrage-pre-analysis.md +0 -115
  142. package/templates/skills/business-analyse/references/cadrage-shared-modules.md +0 -68
  143. package/templates/skills/business-analyse/references/cadrage-structure-cards.md +0 -85
  144. package/templates/skills/business-analyse/references/team-orchestration.md +0 -1093
  145. package/templates/skills/business-analyse/references/validate-incremental-html.md +0 -121
  146. package/templates/skills/business-analyse/steps/step-01b-applications.md +0 -419
  147. package/templates/skills/business-analyse/steps/step-02-decomposition.md +0 -387
  148. package/templates/skills/business-analyse/steps/step-03a-data.md +0 -16
  149. package/templates/skills/business-analyse/steps/step-03a1-setup.md +0 -486
  150. package/templates/skills/business-analyse/steps/step-03a2-analysis.md +0 -300
  151. package/templates/skills/business-analyse/steps/step-03b-ui.md +0 -405
  152. package/templates/skills/business-analyse/steps/step-03c-compile.md +0 -516
  153. package/templates/skills/business-analyse/steps/step-03d-validate.md +0 -691
  154. package/templates/skills/business-analyse/steps/step-04-consolidation.md +0 -17
  155. package/templates/skills/business-analyse/steps/step-04a-collect.md +0 -415
  156. package/templates/skills/business-analyse/steps/step-04b-analyze.md +0 -163
  157. package/templates/skills/business-analyse/steps/step-04c-decide.md +0 -186
  158. package/templates/skills/business-analyse/steps/step-05a-handoff.md +0 -937
  159. package/templates/skills/business-analyse/steps/step-05b-deploy.md +0 -522
  160. package/templates/skills/business-analyse/steps/step-05c-ralph-readiness.md +0 -703
@@ -231,9 +231,9 @@ public class {Name} : BaseEntity, IScopedTenantEntity, IAuditableEntity
231
231
 
232
232
  ### Entity Pattern — Person Extension (User-linked roles)
233
233
 
234
- For entities representing a "person role" of a User (Employee, Customer, Contact). Avoids duplicating User personal data.
234
+ For entities representing a "person role" of a User (Employee, Customer, Contact). Links entity to User instead of duplicating personal data.
235
235
 
236
- > **Full reference:** See `references/person-extension-pattern.md` for complete entity, config, service, DTO, and frontend patterns.
236
+ > **Full reference:** See `references/person-extension-pattern.md` for complete entity, config, service, DTO, and frontend patterns with C# templates, decision guide, and examples.
237
237
 
238
238
  **Two variants:**
239
239
 
@@ -242,9 +242,18 @@ For entities representing a "person role" of a User (Employee, Customer, Contact
242
242
  | **Mandatory** | `Guid UserId` | Employee, Manager — always a User |
243
243
  | **Optional** | `Guid? UserId` | Customer, Contact — may or may not have account |
244
244
 
245
+ **IPersonExtension interface:**
246
+ ```csharp
247
+ public interface IPersonExtension
248
+ {
249
+ Guid? UserId { get; }
250
+ User? User { get; }
251
+ }
252
+ ```
253
+
245
254
  **Mandatory variant (entity):**
246
255
  ```csharp
247
- public class Employee : BaseEntity, ITenantEntity, IAuditableEntity
256
+ public class Employee : BaseEntity, ITenantEntity, IAuditableEntity, IPersonExtension
248
257
  {
249
258
  public Guid TenantId { get; private set; }
250
259
  public string? CreatedBy { get; set; }
@@ -254,7 +263,7 @@ public class Employee : BaseEntity, ITenantEntity, IAuditableEntity
254
263
  public Guid UserId { get; private set; }
255
264
  public User? User { get; private set; }
256
265
 
257
- // Business properties ONLY — ZERO person fields (FirstName, LastName, Email come from User)
266
+ // Business properties ONLY — no duplicate person fields
258
267
  public string Code { get; private set; } = null!;
259
268
  public DateOnly HireDate { get; private set; }
260
269
  }
@@ -262,7 +271,7 @@ public class Employee : BaseEntity, ITenantEntity, IAuditableEntity
262
271
 
263
272
  **Optional variant (entity):**
264
273
  ```csharp
265
- public class Customer : BaseEntity, ITenantEntity, IAuditableEntity
274
+ public class Customer : BaseEntity, ITenantEntity, IAuditableEntity, IPersonExtension
266
275
  {
267
276
  public Guid TenantId { get; private set; }
268
277
  public string? CreatedBy { get; set; }
@@ -272,7 +281,7 @@ public class Customer : BaseEntity, ITenantEntity, IAuditableEntity
272
281
  public Guid? UserId { get; private set; }
273
282
  public User? User { get; private set; }
274
283
 
275
- // Person fields (standalone when no User linked)
284
+ // Person fields (used only when UserId is null)
276
285
  public string FirstName { get; private set; } = null!;
277
286
  public string LastName { get; private set; } = null!;
278
287
  public string? Email { get; private set; }
@@ -284,14 +293,11 @@ public class Customer : BaseEntity, ITenantEntity, IAuditableEntity
284
293
  }
285
294
  ```
286
295
 
287
- **EF Config (mandatory):** `builder.HasIndex(e => new { e.TenantId, e.UserId }).IsUnique();`
288
- **EF Config (optional):** `builder.HasIndex(e => new { e.TenantId, e.UserId }).IsUnique().HasFilter("[UserId] IS NOT NULL");`
289
-
290
- **Service rules (both):** `Include(x => x.User)` on all queries. Inject `ICoreDbContext` for User reads. CreateAsync verifies User exists + no duplicate `(TenantId, UserId)`.
291
-
292
- **DTO rules:** Mandatory CreateDto has `Guid UserId` + business fields only. Optional CreateDto has `Guid? UserId` + person fields. ResponseDto (both) includes `Display*` fields.
293
-
294
- **FORBIDDEN (mandatory variant):** `FirstName`, `LastName`, `Email`, `PhoneNumber` properties in entity — these come from User.
296
+ **Key rules:**
297
+ - **EF Config (mandatory):** Unique index on `(TenantId, UserId)` without filter
298
+ - **EF Config (optional):** Unique index on `(TenantId, UserId)` with `.HasFilter("[UserId] IS NOT NULL")`
299
+ - **Service:** Include User on all queries. Verify User exists and no duplicate on CreateAsync.
300
+ - **DTO:** Mandatory CreateDto requires `UserId`. Optional CreateDto requires person fields when `UserId` is null.
295
301
 
296
302
  ---
297
303
 
@@ -354,9 +360,9 @@ public class {Name}Configuration : IEntityTypeConfiguration<{Name}>
354
360
 
355
361
  ---
356
362
 
357
- ## Service Pattern (tenant-scoped, MANDATORY)
363
+ ## Service Pattern (tenant-scoped, required)
358
364
 
359
- > **CRITICAL:** ALL services MUST inject `ICurrentUserService` + `ICurrentTenantService` and filter by `TenantId`. Missing TenantId = OWASP A01 vulnerability.
365
+ > All services must inject `ICurrentUserService` + `ICurrentTenantService` and filter by `TenantId`. Missing TenantId is an OWASP A01 vulnerability.
360
366
 
361
367
  ```csharp
362
368
  using Microsoft.EntityFrameworkCore;
@@ -392,12 +398,12 @@ public class {Name}Service : I{Name}Service
392
398
  int pageSize = 20,
393
399
  CancellationToken ct = default)
394
400
  {
395
- // MANDATORY guard — throws 400 if no tenant context (e.g., missing X-Tenant-Slug header)
401
+ // Guard clause — throws 400 if no tenant context (e.g., missing X-Tenant-Slug header)
396
402
  var tenantId = _currentTenant.TenantId
397
403
  ?? throw new TenantContextRequiredException();
398
404
 
399
405
  var query = _db.{Name}s
400
- .Where(x => x.TenantId == tenantId) // MANDATORY tenant filter
406
+ .Where(x => x.TenantId == tenantId) // Required tenant filter
401
407
  .AsNoTracking();
402
408
 
403
409
  // Search filter — enables EntityLookup on frontend
@@ -425,7 +431,7 @@ public class {Name}Service : I{Name}Service
425
431
  ?? throw new TenantContextRequiredException();
426
432
 
427
433
  return await _db.{Name}s
428
- .Where(x => x.Id == id && x.TenantId == tenantId) // MANDATORY
434
+ .Where(x => x.Id == id && x.TenantId == tenantId) // Required
429
435
  .AsNoTracking()
430
436
  .Select(x => new {Name}ResponseDto(x.Id, x.Code, x.Name, x.CreatedAt))
431
437
  .FirstOrDefaultAsync(ct);
@@ -437,7 +443,7 @@ public class {Name}Service : I{Name}Service
437
443
  ?? throw new TenantContextRequiredException();
438
444
 
439
445
  var entity = {Name}.Create(
440
- tenantId: tenantId, // MANDATORY — never Guid.Empty
446
+ tenantId: tenantId, // Required — never Guid.Empty
441
447
  code: dto.Code,
442
448
  name: dto.Name);
443
449
 
@@ -472,7 +478,7 @@ public class {Name}Service : I{Name}Service
472
478
  - `ICurrentTenantService` (from `SmartStack.Application.Common.Interfaces.Tenants`): provides `TenantId` (Guid?), `HasTenant` (bool), `TenantSlug` (string?)
473
479
  - `IExtensionsDbContext` (for client extensions) or `ICoreDbContext` (for platform)
474
480
 
475
- **MANDATORY guard clause (first line of every method):**
481
+ **Guard clause (first line of every method):**
476
482
  ```csharp
477
483
  var tenantId = _currentTenant.TenantId
478
484
  ?? throw new TenantContextRequiredException();
@@ -480,7 +486,7 @@ var tenantId = _currentTenant.TenantId
480
486
  This converts a null TenantId into a clean 400 Bad Request response via `GlobalExceptionHandlerMiddleware`.
481
487
  **IMPORTANT:** Uses `TenantContextRequiredException` (400), NOT `UnauthorizedAccessException` (401). A missing tenant is a bad request, not an auth failure — the JWT is valid, `[Authorize]` passed.
482
488
 
483
- **FORBIDDEN in services:**
489
+ Do not use in services:
484
490
  - `_currentTenant.TenantId!.Value` — throws `InvalidOperationException` (500) instead of clean 400
485
491
  - `UnauthorizedAccessException("Tenant context is required")` — throws 401, triggers frontend token clearing
486
492
  - `tenantId: Guid.Empty` — always use validated tenantId from guard clause
@@ -557,18 +563,18 @@ public class {Name}Controller : ControllerBase
557
563
  }
558
564
  ```
559
565
 
560
- **CRITICAL — Route attribute rules:**
566
+ Route attribute rules:
561
567
  - `[NavRoute]` is the ONLY route attribute needed — it resolves routes dynamically from Navigation entities at startup
562
- - **FORBIDDEN:** `[Route("api/...")]` alongside `[NavRoute]` — causes route conflicts and 404s at runtime
563
- - **FORBIDDEN:** `[Route("api/[controller]")]` — this is standard ASP.NET Core, NOT SmartStack
568
+ - Do not use `[Route("api/...")]` alongside `[NavRoute]` — causes route conflicts and 404s at runtime
569
+ - Do not use `[Route("api/[controller]")]` — this is standard ASP.NET Core, NOT SmartStack
564
570
  - If a controller has `[NavRoute]`, there must be NO `[Route]` attribute on the class
565
571
 
566
- **CRITICAL:** Use `[RequirePermission(Permissions.{Module}.{Action})]` on EVERY endpoint — NEVER `[Authorize]` alone (no RBAC enforcement).
572
+ Use `[RequirePermission(Permissions.{Module}.{Action})]` on every endpoint — do not use `[Authorize]` alone (no RBAC enforcement).
567
573
 
568
- **CRITICAL — Permission paths use IDENTICAL segments to NavRoute codes (kebab-case):**
574
+ Permission paths must use identical segments to NavRoute codes (kebab-case):
569
575
  - NavRoute: `human-resources.employees` → Permission: `human-resources.employees.read`
570
576
  - NavRoute: `human-resources.employees.leaves` → Permission: `human-resources.employees.leaves.read`
571
- - FORBIDDEN: `humanresources.employees.read` (no kebab-case — mismatches NavRoute)
577
+ - Do not use: `humanresources.employees.read` (no kebab-case — mismatches NavRoute)
572
578
  - SmartStack.app convention: `support-client.my-tickets.read` (always kebab-case)
573
579
 
574
580
  ### Section-Level Controller (NavRoute with 3 segments)
@@ -636,16 +642,16 @@ public class AiPromptsController : ControllerBase
636
642
  public async Task<ActionResult<PaginatedResult<LeaveTypeResponseDto>>> GetAllLeaveTypes(...)
637
643
  ```
638
644
 
639
- > **CRITICAL — Sub-resource frontend completeness:**
645
+ > Sub-resource frontend completeness:
640
646
  > If a parent page has a button (e.g., "Manage Leave Types") that `navigate()`s to a sub-resource route,
641
- > the frontend MUST include a page component for that route. Otherwise → dead link → white screen.
647
+ > the frontend must include a page component for that route. Otherwise → dead link → white screen.
642
648
  > - Either create a dedicated sub-resource ListPage (e.g., `LeaveTypesPage.tsx`)
643
- > - Or DON'T include the navigate() button if pages won't be created
644
- > - **Prefer separate controllers** (with Suffix) over sub-endpoints in parent controller — easier to route
649
+ > - Or do not include the navigate() button if pages won't be created
650
+ > - Prefer separate controllers (with Suffix) over sub-endpoints in parent controller — easier to route
645
651
 
646
652
  ---
647
653
 
648
- ## Navigation Seed Data Pattern (CRITICAL — routes must be full paths)
654
+ ## Navigation Seed Data Pattern (routes must be full paths)
649
655
 
650
656
  > **The navigation seed data defines menu routes stored in DB. These routes MUST be full paths starting with `/`.**
651
657
  > Short routes (e.g., `humanresources`) cause 400 Bad Request on application-tracking.
@@ -659,12 +665,12 @@ public async Task<ActionResult<PaginatedResult<LeaveTypeResponseDto>>> GetAllLea
659
665
  | Section | `/{app-kebab}/{module-kebab}/{section-kebab}` | `/human-resources/employees/departments` |
660
666
  | Resource | `/{app-kebab}/{module-kebab}/{section-kebab}/{resource-kebab}` | `/human-resources/employees/departments/export` |
661
667
 
662
- **ROUTE SPECIAL CASES (list and detail sections):**
668
+ **Route special cases (list and detail sections):**
663
669
  > The `list` and `detail` sections are NOT functional sub-areas — they are view modes of the module itself.
664
- > Their navigation routes MUST NOT add extra segments:
670
+ > Their navigation routes must NOT add extra segments:
665
671
  > - `list` section route = module route (e.g., `/human-resources/employees`)
666
672
  > - `detail` section route = module route + `/:id` (e.g., `/human-resources/employees/:id`)
667
- > - FORBIDDEN: `/employees/list`, `/employees/detail/:id`
673
+ > - Do not use: `/employees/list`, `/employees/detail/:id`
668
674
  > - Other sections (dashboard, approve, import, etc.) = module route + `/{section-kebab}` (normal behavior)
669
675
 
670
676
  **Rules:**
@@ -716,13 +722,13 @@ var section = NavigationSection.Create(
716
722
  10);
717
723
  ```
718
724
 
719
- ### FORBIDDEN in Seed Data
725
+ ### Avoid in Seed Data
720
726
 
721
727
  | Mistake | Reality |
722
728
  |---------|---------|
723
729
  | `"humanresources"` as route | Must be `"/human-resources"` (full path, kebab-case) |
724
730
  | `"employees"` as route | Must be `"/human-resources/employees"` (includes parent) |
725
- | Deterministic/sequential/fixed GUIDs in seed data | ALWAYS use `Guid.NewGuid()` |
731
+ | Deterministic/sequential/fixed GUIDs in seed data | Use `Guid.NewGuid()` instead |
726
732
  | Missing translations | Must have 4 languages: fr, en, it, de |
727
733
  | Missing NavigationApplicationSeedData | Menu invisible without Application level |
728
734
 
@@ -750,7 +756,7 @@ services.AddValidatorsFromAssemblyContaining<Create{Name}DtoValidator>();
750
756
 
751
757
  ---
752
758
 
753
- ## DTO Type Mapping (CRITICAL)
759
+ ## DTO Type Mapping
754
760
 
755
761
  > **Use the correct .NET type for each property.** Incorrect types cause runtime parsing errors.
756
762
 
@@ -762,7 +768,7 @@ services.AddValidatorsFromAssemblyContaining<Create{Name}DtoValidator>();
762
768
  | Duration, hours | `decimal` | `8.5` | `public decimal HoursWorked { get; set; }` |
763
769
  | FK reference | `Guid` | `"uuid-string"` | `public Guid EmployeeId { get; set; }` |
764
770
 
765
- **FORBIDDEN in DTOs:**
771
+ Do not use in DTOs:
766
772
  - `string Date` / `string StartDate` — use `DateOnly`
767
773
  - `string Time` — use `TimeOnly`
768
774
  - `DateTime BirthDate` — use `DateOnly` (no time component needed)
@@ -780,7 +786,7 @@ services.AddValidatorsFromAssemblyContaining<Create{Name}DtoValidator>();
780
786
  | `e.IsDeleted` filter | Does NOT exist — no soft delete |
781
787
  | `SmartStack.Api.Core.Routing` | Wrong — use `SmartStack.Api.Routing` |
782
788
  | `SystemEntity` base class | Does NOT exist — use `BaseEntity` for all |
783
- | `[Route("api/...")] + [NavRoute]` | **FORBIDDEN** — causes 404s. Only `[NavRoute]` needed (resolves route from DB at startup). Remove ALL `[Route]` attributes when `[NavRoute]` is present. |
789
+ | `[Route("api/...")] + [NavRoute]` | Do not combine — causes 404s. Only `[NavRoute]` needed (resolves route from DB at startup). Remove `[Route]` when `[NavRoute]` is present. |
784
790
  | `SmartStack.Domain.Common.Interfaces` | Wrong — interfaces are in `SmartStack.Domain.Common` directly |
785
791
  | `[Authorize]` without `[RequirePermission]` | No RBAC enforcement — always use `[RequirePermission]` |
786
792
  | `tenantId: Guid.Empty` in services | OWASP A01 — always use validated `_currentTenant.TenantId` |
@@ -793,11 +799,11 @@ services.AddValidatorsFromAssemblyContaining<Create{Name}DtoValidator>();
793
799
  | `humanresources.employees.read` in permissions | Permission segments MUST match NavRoute kebab-case: `human-resources.employees.read` |
794
800
  | `Permission.Create()` | Does NOT exist — use `CreateForModule()`, `CreateForSection()`, etc. |
795
801
  | `GetAllAsync()` without search param | ALL GetAll endpoints MUST support `?search=` for EntityLookup |
796
- | `string Date` in DTO | Date-only fields MUST use `DateOnly`, NEVER `string` |
802
+ | `string Date` in DTO | Date-only fields must use `DateOnly`, not `string` |
797
803
  | `DateTime` for date-only | Use `DateOnly` when no time component needed |
798
804
  | FK field as plain text input | Frontend MUST use `EntityLookup` component for Guid FK fields |
799
- | `PagedResult<T>` / `PaginatedResultDto<T>` | FORBIDDEN — use `PaginatedResult<T>` only |
800
- | Controller injects `DbContext` | **Clean Architecture violation** — create an Application service and inject it instead |
805
+ | `PagedResult<T>` / `PaginatedResultDto<T>` | Use `PaginatedResult<T>` instead |
806
+ | Controller injects `DbContext` | Create an Application service and inject it instead (Clean Architecture) |
801
807
  | Domain entity has `[Table]` attribute | Infrastructure concern in Domain — move to `IEntityTypeConfiguration<T>` in Infrastructure |
802
808
  | `using Microsoft.EntityFrameworkCore` in Domain | EF Core belongs in Infrastructure, not Domain — Domain must be persistence-ignorant |
803
809
  | Controller returns `Employee` entity | Domain leak in API response — return `EmployeeResponseDto` instead |
@@ -949,10 +955,10 @@ export interface PaginationParams {
949
955
  }
950
956
  ```
951
957
 
952
- ### FORBIDDEN Type Names
958
+ ### Type Names to Avoid
953
959
 
954
- | Forbidden | Canonical Replacement |
955
- |-----------|----------------------|
960
+ | Avoid | Use Instead |
961
+ |-------|------------|
956
962
  | `PagedResult<T>` | `PaginatedResult<T>` |
957
963
  | `PaginatedResultDto<T>` | `PaginatedResult<T>` |
958
964
  | `PaginatedResponse<T>` | `PaginatedResult<T>` |
@@ -968,8 +974,8 @@ export interface PaginationParams {
968
974
  - **Max pageSize = 100** — enforced via `Math.Clamp(pageSize, 1, 100)` or extension method
969
975
  - **Default page = 1, pageSize = 20** — all GetAll endpoints
970
976
  - **Search param mandatory** — enables `EntityLookup` on frontend
971
- - **POST-CHECK 11** blocks `List<T>` returns on GetAll
972
- - **POST-CHECK 26** blocks non-canonical pagination type names
977
+ - **POST-CHECK C12** blocks `List<T>` returns on GetAll
978
+ - **POST-CHECK C28** blocks non-canonical pagination type names
973
979
 
974
980
  ---
975
981
 
@@ -977,7 +983,7 @@ export interface PaginationParams {
977
983
 
978
984
  > **These are the most common and dangerous mistakes.** Each one has been observed in production code generation.
979
985
 
980
- ### Anti-Pattern 1: HasQueryFilter with `!= Guid.Empty` (SECURITY — OWASP A01)
986
+ ### Anti-Pattern 1: HasQueryFilter with `!= Guid.Empty` (Security vulnerability)
981
987
 
982
988
  The `HasQueryFilter` in EF Core should use **runtime tenant resolution**, NOT a static comparison against `Guid.Empty`.
983
989
 
@@ -992,11 +998,11 @@ public void Configure(EntityTypeBuilder<MyEntity> builder)
992
998
 
993
999
  **CORRECT — Tenant isolation via service:**
994
1000
  ```csharp
995
- // CORRECT: In SmartStack, tenant filtering is done in the SERVICE layer, not via HasQueryFilter.
1001
+ // Correct: In SmartStack, tenant filtering is done in the SERVICE layer, not via HasQueryFilter.
996
1002
  public async Task<PaginatedResult<MyEntityDto>> GetAllAsync(...)
997
1003
  {
998
1004
  var query = _db.MyEntities
999
- .Where(x => x.TenantId == _currentUser.TenantId) // MANDATORY runtime filter
1005
+ .Where(x => x.TenantId == _currentUser.TenantId) // Required runtime filter
1000
1006
  .AsNoTracking();
1001
1007
  // ...
1002
1008
  }
@@ -1022,7 +1028,7 @@ public async Task<List<MyEntityDto>> GetAllAsync(CancellationToken ct)
1022
1028
 
1023
1029
  **CORRECT — Paginated with search:**
1024
1030
  ```csharp
1025
- // CORRECT: Returns PaginatedResult<T> with search, page, pageSize
1031
+ // Correct: Returns PaginatedResult<T> with search, page, pageSize
1026
1032
  public async Task<PaginatedResult<MyEntityDto>> GetAllAsync(
1027
1033
  string? search = null, int page = 1, int pageSize = 20, CancellationToken ct = default)
1028
1034
  {
@@ -1128,16 +1134,16 @@ public class UpdateMyEntityDtoValidator : AbstractValidator<UpdateMyEntityDto>
1128
1134
 
1129
1135
  ---
1130
1136
 
1131
- ### Anti-Pattern 6: `TenantId!.Value` null-forgiving operator (RUNTIME CRASH)
1137
+ ### Anti-Pattern 6: `TenantId!.Value` null-forgiving operator
1132
1138
 
1133
1139
  The `!` (null-forgiving) operator followed by `.Value` on a `Guid?` suppresses compiler warnings but **throws `InvalidOperationException` at runtime** when TenantId is null.
1134
1140
 
1135
1141
  **INCORRECT — Crashes with 500 Internal Server Error:**
1136
1142
  ```csharp
1137
- // WRONG: Throws InvalidOperationException("Nullable object must have a value") → 500 error
1143
+ // Wrong: Throws InvalidOperationException("Nullable object must have a value") → 500 error
1138
1144
  public async Task<PaginatedResult<MyEntityDto>> GetAllAsync(...)
1139
1145
  {
1140
- var tenantId = _currentTenant.TenantId!.Value; // CRASH if no tenant context
1146
+ var tenantId = _currentTenant.TenantId!.Value; // Crashes if no tenant context
1141
1147
  var query = _db.MyEntities.Where(x => x.TenantId == tenantId);
1142
1148
  // ...
1143
1149
  }
@@ -1145,7 +1151,7 @@ public async Task<PaginatedResult<MyEntityDto>> GetAllAsync(...)
1145
1151
 
1146
1152
  **CORRECT — Clean 400 via GlobalExceptionHandlerMiddleware:**
1147
1153
  ```csharp
1148
- // CORRECT: Throws TenantContextRequiredException → middleware converts to 400 Bad Request
1154
+ // Correct: Throws TenantContextRequiredException → middleware converts to 400 Bad Request
1149
1155
  public async Task<PaginatedResult<MyEntityDto>> GetAllAsync(...)
1150
1156
  {
1151
1157
  var tenantId = _currentTenant.TenantId