@atlashub/smartstack-cli 3.43.0 → 3.45.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 (47) hide show
  1. package/dist/mcp-entry.mjs +201 -22
  2. package/dist/mcp-entry.mjs.map +1 -1
  3. package/package.json +1 -1
  4. package/templates/agents/efcore/conflicts.md +22 -2
  5. package/templates/agents/efcore/migration.md +11 -0
  6. package/templates/agents/efcore/rebase-snapshot.md +7 -0
  7. package/templates/agents/efcore/scan.md +24 -2
  8. package/templates/agents/efcore/squash.md +7 -0
  9. package/templates/agents/gitflow/init.md +195 -12
  10. package/templates/skills/apex/SKILL.md +14 -9
  11. package/templates/skills/apex/_shared.md +3 -0
  12. package/templates/skills/apex/references/analysis-methods.md +1 -1
  13. package/templates/skills/apex/references/challenge-questions.md +21 -0
  14. package/templates/skills/apex/references/core-seed-data.md +59 -104
  15. package/templates/skills/apex/references/post-checks.md +289 -225
  16. package/templates/skills/apex/references/smartstack-api.md +33 -35
  17. package/templates/skills/apex/references/smartstack-frontend.md +99 -3
  18. package/templates/skills/apex/references/smartstack-layers.md +145 -23
  19. package/templates/skills/apex/steps/step-00-init.md +2 -2
  20. package/templates/skills/apex/steps/step-01-analyze.md +1 -0
  21. package/templates/skills/apex/steps/step-02-plan.md +4 -3
  22. package/templates/skills/apex/steps/step-03-execute.md +24 -24
  23. package/templates/skills/apex/steps/step-04-examine.md +64 -24
  24. package/templates/skills/apex/steps/step-05-deep-review.md +1 -1
  25. package/templates/skills/apex/steps/step-08-run-tests.md +21 -13
  26. package/templates/skills/application/references/application-roles-template.md +10 -15
  27. package/templates/skills/application/references/backend-entity-seeding.md +6 -5
  28. package/templates/skills/application/references/backend-seeding-and-dto-output.md +1 -1
  29. package/templates/skills/application/references/nav-fallback-procedure.md +14 -17
  30. package/templates/skills/application/references/provider-template.md +5 -5
  31. package/templates/skills/application/references/roles-client-project-handling.md +1 -1
  32. package/templates/skills/application/references/roles-fallback-procedure.md +10 -15
  33. package/templates/skills/application/steps/step-01-navigation.md +1 -1
  34. package/templates/skills/application/steps/step-02-permissions.md +3 -3
  35. package/templates/skills/application/steps/step-03b-provider.md +1 -0
  36. package/templates/skills/application/templates-seed.md +41 -47
  37. package/templates/skills/business-analyse/references/team-orchestration.md +2 -2
  38. package/templates/skills/controller/steps/step-04-perms.md +1 -1
  39. package/templates/skills/efcore/references/troubleshooting.md +2 -2
  40. package/templates/skills/efcore/steps/rebase-snapshot/step-00-init.md +2 -2
  41. package/templates/skills/efcore/steps/squash/step-00-init.md +2 -2
  42. package/templates/skills/apex/references/examine-build-validation.md +0 -82
  43. package/templates/skills/apex/references/execution-frontend-gates.md +0 -177
  44. package/templates/skills/apex/references/execution-frontend-patterns.md +0 -105
  45. package/templates/skills/apex/references/execution-layer1-rules.md +0 -96
  46. package/templates/skills/apex/references/initialization-challenge-flow.md +0 -110
  47. package/templates/skills/apex/references/planning-layer-mapping.md +0 -151
@@ -505,12 +505,12 @@ public class {Name}Controller : ControllerBase
505
505
  - FORBIDDEN: `humanresources.employees.read` (no kebab-case — mismatches NavRoute)
506
506
  - SmartStack.app convention: `support-client.my-tickets.read` (always kebab-case)
507
507
 
508
- ### Section-Level Controller (NavRoute with 4 segments)
508
+ ### Section-Level Controller (NavRoute with 3 segments)
509
509
 
510
- When a module has sections, each section gets its own controller with a 4-segment navRoute:
510
+ When a module has sections, each section gets its own controller with a 3-segment navRoute:
511
511
 
512
512
  ```csharp
513
- // Section-level controller: navRoute has 4 segments
513
+ // Section-level controller: navRoute has 3 segments
514
514
  [ApiController]
515
515
  [NavRoute("{app}.{module}.{section}")]
516
516
  [Authorize]
@@ -528,11 +528,17 @@ public class {Section}Controller : ControllerBase
528
528
  }
529
529
  ```
530
530
 
531
- **NavRoute segment rules:**
531
+ **NavRoute segment rules (minimum 2 segments):**
532
532
  | Level | NavRoute format | Example |
533
533
  |-------|----------------|---------|
534
- | Module | `{app}.{module}` (2 segments) | `human-resources.employees` |
535
- | Section | `{app}.{module}.{section}` (3 segments) | `human-resources.employees.departments` |
534
+ | Module | `{app}.{module}` (2 segments) | `administration.users` |
535
+ | Section | `{app}.{module}.{section}` (3 segments) | `administration.users.groups` |
536
+ | Sub-resource (Suffix) | `{app}.{module}` + Suffix | `administration.ai` + `Suffix = "prompts"` |
537
+
538
+ > **POST-CONTEXT REMOVAL:** The old "context" level (1st segment) has been removed.
539
+ > Before: `platform.administration.users` (3 segments). After: `administration.users` (2 segments).
540
+ > The NavigationRouteRegistryBuilder builds 2-segment paths from DB (application.module).
541
+ > Controllers with 3+ segments use the fallback route generator (dots → slashes).
536
542
 
537
543
  **Namespace:** `SmartStack.Api.Routing` (NOT `SmartStack.Api.Core.Routing`)
538
544
 
@@ -540,18 +546,18 @@ public class {Section}Controller : ControllerBase
540
546
 
541
547
  ### Sub-Resource Pattern (NavRoute Suffix)
542
548
 
543
- When an entity is a child of another entity (e.g., LeaveTypes under Leaves), use `[NavRoute(..., Suffix = "types")]`:
549
+ When an entity is a child of another entity (e.g., AiPrompts under AI), use `[NavRoute(..., Suffix = "...")]`:
544
550
 
545
551
  ```csharp
546
- // Sub-resource controller: types are nested under leaves
552
+ // Sub-resource controller: prompts are nested under AI module
547
553
  [ApiController]
548
- [NavRoute("human-resources.employees.leaves", Suffix = "types")]
554
+ [NavRoute("administration.ai", Suffix = "prompts")]
549
555
  [Authorize]
550
- public class LeaveTypesController : ControllerBase
556
+ public class AiPromptsController : ControllerBase
551
557
  {
552
558
  [HttpGet]
553
- [RequirePermission(Permissions.Leaves.Read)] // inherits parent section permission
554
- public async Task<ActionResult<PaginatedResult<LeaveTypeResponseDto>>> GetAll(...)
559
+ [RequirePermission(Permissions.Ai.Prompts.Read)]
560
+ public async Task<ActionResult<PaginatedResult<AiPromptResponseDto>>> GetAll(...)
555
561
  => Ok(await _service.GetAllAsync(search, page, pageSize, ct));
556
562
  }
557
563
  ```
@@ -610,28 +616,13 @@ private static string ToKebabCase(string value)
610
616
  .ToLowerInvariant();
611
617
  ```
612
618
 
613
- ### SeedConstants Pattern
619
+ ### GUID Generation Rule
614
620
 
615
621
  ```csharp
616
- public static class SeedConstants
617
- {
618
- // Deterministic GUIDs (SHA256-based, reproducible across environments)
619
- // NOTE: Application/Module/Section/Resource IDs are deterministic.
620
- public static readonly Guid ApplicationId = DeterministicGuid("nav:human-resources");
621
- public static readonly Guid ModuleId = DeterministicGuid("nav:human-resources.employees");
622
- public static readonly Guid SectionId = DeterministicGuid("nav:human-resources.employees.departments");
623
-
624
- private static Guid DeterministicGuid(string input)
625
- {
626
- var hash = System.Security.Cryptography.SHA256.HashData(
627
- System.Text.Encoding.UTF8.GetBytes(input));
628
- var bytes = new byte[16];
629
- Array.Copy(hash, bytes, 16);
630
- bytes[6] = (byte)((bytes[6] & 0x0F) | 0x50); // version 5
631
- bytes[8] = (byte)((bytes[8] & 0x3F) | 0x80); // variant
632
- return new Guid(bytes);
633
- }
634
- }
622
+ // ALWAYS use Guid.NewGuid() for ALL seed data IDs
623
+ // Avoids conflicts between projects/tenants/environments
624
+ // Idempotence is handled by Code-based lookups at runtime
625
+ // Navigation entities are resolved by Code, not by fixed GUIDs
635
626
  ```
636
627
 
637
628
  ### Navigation Seed Data Example
@@ -665,7 +656,7 @@ var section = NavigationSection.Create(
665
656
  |---------|---------|
666
657
  | `"humanresources"` as route | Must be `"/human-resources"` (full path, kebab-case) |
667
658
  | `"employees"` as route | Must be `"/human-resources/employees"` (includes parent) |
668
- | `Guid.NewGuid()` in seed data | Must use deterministic GUIDs (SHA256) |
659
+ | Deterministic/sequential/fixed GUIDs in seed data | ALWAYS use `Guid.NewGuid()` |
669
660
  | Missing translations | Must have 4 languages: fr, en, it, de |
670
661
  | Missing NavigationApplicationSeedData | Menu invisible without Application level |
671
662
 
@@ -740,6 +731,13 @@ services.AddValidatorsFromAssemblyContaining<Create{Name}DtoValidator>();
740
731
  | `DateTime` for date-only | Use `DateOnly` when no time component needed |
741
732
  | FK field as plain text input | Frontend MUST use `EntityLookup` component for Guid FK fields |
742
733
  | `PagedResult<T>` / `PaginatedResultDto<T>` | FORBIDDEN — use `PaginatedResult<T>` only |
734
+ | Controller injects `DbContext` | **Clean Architecture violation** — create an Application service and inject it instead |
735
+ | Domain entity has `[Table]` attribute | Infrastructure concern in Domain — move to `IEntityTypeConfiguration<T>` in Infrastructure |
736
+ | `using Microsoft.EntityFrameworkCore` in Domain | EF Core belongs in Infrastructure, not Domain — Domain must be persistence-ignorant |
737
+ | Controller returns `Employee` entity | Domain leak in API response — return `EmployeeResponseDto` instead |
738
+ | `IEmployeeService.cs` in Infrastructure | Interface belongs in Application — move to `Application/Interfaces/` |
739
+ | Service implementation in Application layer | Implementations belong in Infrastructure — Application only contains interfaces |
740
+ | Controller injects `IRepository<T>` directly | Controllers use Application services, not repositories — add a service layer |
743
741
 
744
742
  ---
745
743
 
@@ -861,8 +859,8 @@ export interface PaginationParams {
861
859
  - **Max pageSize = 100** — enforced via `Math.Clamp(pageSize, 1, 100)` or extension method
862
860
  - **Default page = 1, pageSize = 20** — all GetAll endpoints
863
861
  - **Search param mandatory** — enables `EntityLookup` on frontend
864
- - **POST-CHECK 16** blocks `List<T>` returns on GetAll
865
- - **POST-CHECK 31** blocks non-canonical pagination type names
862
+ - **POST-CHECK 11** blocks `List<T>` returns on GetAll
863
+ - **POST-CHECK 26** blocks non-canonical pagination type names
866
864
 
867
865
  ---
868
866
 
@@ -211,7 +211,7 @@ resources: {
211
211
  ns: ['common', 'navigation', 'employees', 'projects', 'clients'],
212
212
  ```
213
213
 
214
- POST-CHECK 45 validates this. Unregistered namespaces → BLOCKING.
214
+ POST-CHECK 37 validates this. Unregistered namespaces → BLOCKING.
215
215
 
216
216
  ### Rules
217
217
 
@@ -407,7 +407,7 @@ const handleTabClick = (tab: TabKey) => {
407
407
  - Users expect tabs to switch content in-place, not redirect to a different page
408
408
  - The browser back button should go to the list page, not toggle between tabs
409
409
 
410
- **POST-CHECK 43 enforces this rule.**
410
+ **POST-CHECK 35 enforces this rule.**
411
411
 
412
412
  ---
413
413
 
@@ -1179,7 +1179,7 @@ Before marking frontend tasks as complete, verify:
1179
1179
  - [ ] Translation files exist for **all 4 languages** (fr, en, it, de) in `src/i18n/locales/`
1180
1180
  - [ ] All `t()` calls include namespace prefix AND fallback value
1181
1181
  - [ ] No hardcoded strings in JSX — all text goes through `t()`
1182
- - [ ] CSS uses variables only — no hardcoded Tailwind colors (BLOCKING POST-CHECK 13)
1182
+ - [ ] CSS uses variables only — no hardcoded Tailwind colors (BLOCKING POST-CHECK 9)
1183
1183
  - [ ] Pages follow loading → error → content pattern
1184
1184
  - [ ] Pages use `src/pages/{App}/{Module}/` hierarchy
1185
1185
  - [ ] API calls use generated hooks or `apiClient` (never raw axios)
@@ -1569,3 +1569,99 @@ describe('EntityEditPage', () => {
1569
1569
  - Use `@testing-library/react` + `@testing-library/user-event` (NEVER enzyme)
1570
1570
  - Mock API with `vi.mock()` or MSW — NEVER make real API calls in tests
1571
1571
  - Test files live next to their component (co-located, NOT in a separate `__tests__/` folder)
1572
+
1573
+ ---
1574
+
1575
+ ## 9. Frontend Compliance Gates (5 Mandatory Checks)
1576
+
1577
+ > **Run these checks before any frontend commit.** All 5 gates MUST pass.
1578
+ > Previously in separate files `execution-frontend-gates.md` and `execution-frontend-patterns.md` — now consolidated here.
1579
+
1580
+ ### Gate 1: CSS Variables (Theme System)
1581
+
1582
+ ```bash
1583
+ ALL_PAGES=$(find src/pages/ src/components/ -name "*.tsx" 2>/dev/null | grep -v node_modules | grep -v "\.test\.")
1584
+ if [ -n "$ALL_PAGES" ]; then
1585
+ HARDCODED=$(grep -Pn '(bg|text|border)-(?!\[)(red|blue|green|gray|white|black|slate|zinc|neutral|stone)-' $ALL_PAGES 2>/dev/null)
1586
+ if [ -n "$HARDCODED" ]; then
1587
+ echo "FAIL: Hardcoded Tailwind colors found — must use CSS variables (see section 4)"
1588
+ echo "$HARDCODED"
1589
+ else
1590
+ echo "PASS: CSS variables"
1591
+ fi
1592
+ fi
1593
+ ```
1594
+
1595
+ **Fix mapping:** See section 4 (CSS Variables) for the complete variable reference table.
1596
+
1597
+ ### Gate 2: Forms as Pages (ZERO Modals/Drawers)
1598
+
1599
+ ```bash
1600
+ PAGE_FILES=$(find src/pages/ -name "*.tsx" 2>/dev/null)
1601
+ if [ -n "$PAGE_FILES" ]; then
1602
+ FAIL=false
1603
+ MODAL_IMPORTS=$(grep -Pn "import.*(?:Modal|Dialog|Drawer|Popup|Sheet|SlideOver|Overlay)" $PAGE_FILES 2>/dev/null)
1604
+ if [ -n "$MODAL_IMPORTS" ]; then
1605
+ echo "FAIL: Modal/Dialog/Drawer imports — forms MUST be full pages (see section 3b)"
1606
+ echo "$MODAL_IMPORTS"
1607
+ FAIL=true
1608
+ fi
1609
+ MODAL_STATE=$(grep -Pn "useState.*(?:isOpen|showModal|showDialog|showCreate|showEdit|showForm|isCreating|isEditing|showDrawer|showPanel|showSlideOver|selectedEntity|editingEntity)" $PAGE_FILES 2>/dev/null)
1610
+ if [ -n "$MODAL_STATE" ]; then
1611
+ echo "FAIL: Inline form state detected — forms MUST be separate pages (see section 3b)"
1612
+ echo "$MODAL_STATE"
1613
+ FAIL=true
1614
+ fi
1615
+ if [ "$FAIL" = false ]; then echo "PASS: No modals/drawers"; fi
1616
+ fi
1617
+ ```
1618
+
1619
+ ### Gate 3: I18n File Structure
1620
+
1621
+ ```bash
1622
+ if [ ! -d "src/i18n/locales" ]; then
1623
+ echo "FAIL: Missing src/i18n/locales/ directory"
1624
+ else
1625
+ for LANG in fr en it de; do
1626
+ JSON_FILES=$(find "src/i18n/locales/$LANG" -name "*.json" 2>/dev/null | wc -l)
1627
+ if [ "$JSON_FILES" -eq 0 ]; then
1628
+ echo "FAIL: No JSON files in src/i18n/locales/$LANG/"
1629
+ else
1630
+ echo "PASS: $LANG ($JSON_FILES files)"
1631
+ fi
1632
+ done
1633
+ fi
1634
+ ```
1635
+
1636
+ ### Gate 4: Lazy Loading
1637
+
1638
+ ```bash
1639
+ APP_TSX=$(find src/ -name "App.tsx" -not -path "*/node_modules/*" 2>/dev/null | head -1)
1640
+ ROUTE_FILES=$(find src/routes/ -name "*.tsx" -o -name "*.ts" 2>/dev/null)
1641
+ if [ -n "$APP_TSX" ]; then
1642
+ STATIC_IMPORTS=$(grep -Pn "^import .+ from '@/pages/" "$APP_TSX" $ROUTE_FILES 2>/dev/null)
1643
+ if [ -n "$STATIC_IMPORTS" ]; then
1644
+ echo "FAIL: Static page imports — MUST use React.lazy() (see section 1)"
1645
+ echo "$STATIC_IMPORTS"
1646
+ else
1647
+ echo "PASS: Lazy loading"
1648
+ fi
1649
+ fi
1650
+ ```
1651
+
1652
+ ### Gate 5: useTranslation in Pages
1653
+
1654
+ ```bash
1655
+ PAGE_FILES=$(find src/pages/ -name "*.tsx" 2>/dev/null | grep -v "\.test\." | grep -v node_modules)
1656
+ if [ -n "$PAGE_FILES" ]; then
1657
+ TOTAL=$(echo "$PAGE_FILES" | wc -l)
1658
+ WITH_I18N=$(grep -l "useTranslation" $PAGE_FILES 2>/dev/null | wc -l)
1659
+ if [ "$WITH_I18N" -eq 0 ]; then
1660
+ echo "FAIL: No pages use useTranslation — all text must be translated (see section 2)"
1661
+ else
1662
+ echo "PASS: $WITH_I18N/$TOTAL pages use useTranslation"
1663
+ fi
1664
+ fi
1665
+ ```
1666
+
1667
+ > **ALL 5 gates MUST pass before frontend commit.** When delegating to `/ui-components` skill, include explicit instructions: CSS variables only, forms as full pages, i18n with namespace + fallback.
@@ -5,6 +5,38 @@
5
5
 
6
6
  ---
7
7
 
8
+ ## Layer Isolation Rules (Clean Architecture)
9
+
10
+ ### Dependency Graph (allowed imports)
11
+
12
+ ```
13
+ Domain → (nothing)
14
+ Application → Domain
15
+ Infrastructure → Domain, Application
16
+ Api → Application, Infrastructure
17
+ Web → Application (via API clients)
18
+ ```
19
+
20
+ ### FORBIDDEN Patterns
21
+
22
+ | Layer | FORBIDDEN import | Why |
23
+ |-------|-----------------|-----|
24
+ | Domain | Application, Infrastructure, Api | Domain is the core, depends on nothing |
25
+ | Application | Infrastructure, Api | Application defines interfaces, Infrastructure implements them |
26
+ | Controller | DbContext (direct injection) | Controllers use Application services, not database directly |
27
+ | Controller | IRepository (direct injection) | Controllers use Application services, not repositories |
28
+ | Domain | EF Core attributes (`[Table]`, `[Column]`, `[Index]`) | Domain must be persistence-ignorant; use `IEntityTypeConfiguration<T>` in Infrastructure |
29
+ | Domain | `using Microsoft.EntityFrameworkCore` | Infrastructure concern leaking into Domain |
30
+ | API response | Domain entity (e.g., `ActionResult<Employee>`) | Return DTOs (`EmployeeResponseDto`), never Domain entities |
31
+
32
+ ### Enforcement
33
+
34
+ - **MCP `validate_conventions(checks: ['architecture'])`** — scans `.cs` files for forbidden imports, DbContext injection, entity exposure, and service interface placement
35
+ - **MCP `review_code(checks: ['architecture'])`** — detects layer violations, DbContext in controllers, EF Core attributes in Domain, entity exposure in API responses
36
+ - **POST-CHECKs A1–A7** — bash-based defense-in-depth (see `post-checks.md`)
37
+
38
+ ---
39
+
8
40
  ## Layer 0 — Domain (sequential)
9
41
 
10
42
  **Entities:** `Domain/Entities/{App}/{Module}/`
@@ -51,7 +83,7 @@
51
83
 
52
84
  **BLOCKING:** `dotnet build --no-restore` MUST pass after migration.
53
85
 
54
- > **CRITICAL — Migration must cover ALL entities (POST-CHECK 44, 49):**
86
+ > **CRITICAL — Migration must cover ALL entities (POST-CHECK 36, 40):**
55
87
  > Create/update migration AFTER ALL entities and EF configs are registered in DbContext.
56
88
  > Verify with `dotnet ef migrations has-pending-model-changes` — must report NO pending changes.
57
89
  > If entities are added incrementally across modules, create a NEW migration for each batch.
@@ -82,8 +114,8 @@
82
114
  - CQRS with MediatR
83
115
  - FluentValidation for all commands — **MUST register validators via DI:**
84
116
  `services.AddValidatorsFromAssemblyContaining<Create{Entity}DtoValidator>();`
85
- Without DI registration, `[FromBody]` DTOs are never validated (POST-CHECK 46)
86
- - **Date fields in DTOs MUST use `DateOnly`**, not `string` (POST-CHECK 47). See `smartstack-api.md` DTO Type Mapping.
117
+ Without DI registration, `[FromBody]` DTOs are never validated (POST-CHECK 38)
118
+ - **Date fields in DTOs MUST use `DateOnly`**, not `string` (POST-CHECK 39). See `smartstack-api.md` DTO Type Mapping.
87
119
  - DTOs separate from domain entities
88
120
  - Service interfaces in Application, implementations in Infrastructure
89
121
  - **FORBIDDEN:** `tenantId: Guid.Empty`, `TenantId!.Value`, queries without TenantId filter, `ICurrentUser` (does not exist — use `ICurrentUserService` + `ICurrentTenantService`), `string` type for date fields
@@ -102,6 +134,10 @@
102
134
 
103
135
  **Rules:**
104
136
  - `[RequirePermission(Permissions.{Module}.{Action})]` on EVERY endpoint
137
+ - **NavRoute minimum 2 segments** (application.module):
138
+ - `[NavRoute("human-resources.employees")]` (CORRECT — module-level, 2 segments)
139
+ - `[NavRoute("human-resources.employees.departments")]` (CORRECT — section-level, 3 segments)
140
+ - `[NavRoute("administration.ai", Suffix = "prompts")]` (CORRECT — sub-resource with Suffix)
105
141
  - **NavRoute values MUST use kebab-case for ALL multi-word segments:**
106
142
  - `[NavRoute("human-resources.employees")]` (CORRECT)
107
143
  - `[NavRoute("humanresources.employees")]` (WRONG — missing hyphens)
@@ -109,8 +145,8 @@
109
145
  - `[NavRoute("projectmanagement.projects")]` (WRONG)
110
146
  - Permission paths MUST use kebab-case matching NavRoute codes (e.g., `human-resources.employees.read`)
111
147
  - FORBIDDEN: concatenated segments like `humanresources` — must be `human-resources`
112
- - POST-CHECK 48 detects non-kebab-case NavRoute values. POST-CHECK 41 detects non-kebab-case permissions
113
- - **FORBIDDEN:** `[Route("api/...")]` alongside `[NavRoute]` — causes 404s (POST-CHECK 50)
148
+ - POST-CHECK 32 detects non-kebab-case NavRoute values. POST-CHECK 33 detects non-kebab-case permissions
149
+ - **FORBIDDEN:** `[Route("api/...")]` alongside `[NavRoute]` — causes 404s (POST-CHECK 41)
114
150
  - `[NavRoute]` is the ONLY route attribute needed — resolves routes from DB at startup
115
151
  - NEVER use `[Authorize]` without specific permission
116
152
  - Swagger XML documentation
@@ -136,10 +172,10 @@
136
172
 
137
173
  **Application-level (created ONCE, shared across modules):**
138
174
  1. **NavigationApplicationSeedData.cs** — Application-level navigation entry (MUST be first)
139
- 2. **ApplicationRolesSeedData.cs** — Application-scoped roles (admin, manager, contributor, viewer) with deterministic GUIDs. Provides role entries for SeedRolesAsync().
175
+ 2. **ApplicationRolesSeedData.cs** — Application-scoped roles (admin, manager, contributor, viewer) with random GUIDs (`Guid.NewGuid()`). Provides role entries for SeedRolesAsync().
140
176
 
141
177
  **Per-module:**
142
- 3. **NavigationModuleSeedData.cs** — Deterministic GUIDs (SHA256), 4 languages (fr, en, it, de)
178
+ 3. **NavigationModuleSeedData.cs** — Random GUIDs (`Guid.NewGuid()`), 4 languages (fr, en, it, de)
143
179
  4. **NavigationSectionSeedData.cs** — Section-level navigation (if sections defined)
144
180
  5. **NavigationResourceSeedData.cs** — Resource-level navigation (if resources defined)
145
181
  6. **Permissions.cs** — Static permission constants: `public static class {Module} { public const string Read = "..."; }`. Referenced by `[RequirePermission(Permissions.{Module}.Read)]`.
@@ -154,21 +190,13 @@
154
190
  - `SeedRolePermissionsAsync()` — maps roles to permissions (roles resolved by Code, NOT by GUID)
155
191
  - DI: `services.AddScoped<IClientSeedDataProvider, {App}SeedDataProvider>()`
156
192
 
157
- ### Deterministic GUID Pattern
193
+ ### GUID Generation Rule
158
194
 
159
195
  ```csharp
160
- // Use SHA256 for deterministic GUIDs (reproducible across environments)
161
- // NOTE: Application/Module/Section/Resource IDs are deterministic.
162
- public static readonly Guid ModuleId = GenerateDeterministicGuid("nav-module-{app}-{module}");
163
-
164
- private static Guid GenerateDeterministicGuid(string input)
165
- {
166
- var hash = System.Security.Cryptography.SHA256.HashData(
167
- System.Text.Encoding.UTF8.GetBytes(input));
168
- var bytes = new byte[16];
169
- Array.Copy(hash, bytes, 16);
170
- return new Guid(bytes);
171
- }
196
+ // ALWAYS use Guid.NewGuid() for ALL seed data IDs
197
+ // Avoids conflicts between projects/tenants/environments
198
+ // Idempotence is handled by Code-based lookups at runtime
199
+ public static readonly Guid ModuleId = Guid.NewGuid();
172
200
  ```
173
201
 
174
202
  ### Route Convention (CRITICAL — Full Paths Required)
@@ -217,7 +245,7 @@ var sectionRoute = $"{moduleRoute}/{ToKebabCase(sectionCode)}";
217
245
  > - Other sections (dashboard, approve, import) = module route + `/{section-kebab}` (normal)
218
246
 
219
247
  **FORBIDDEN:**
220
- - `Guid.NewGuid()` → use deterministic GUIDs (SHA256)
248
+ - Deterministic/sequential/fixed GUIDs → ALWAYS use `Guid.NewGuid()`
221
249
  - Missing translations (must have fr, en, it, de)
222
250
  - Empty seed classes with no seeding logic
223
251
  - PascalCase in route URLs → always kebab-case
@@ -275,7 +303,7 @@ const [loading, setLoading] = useState(true);
275
303
  ### Components & CSS
276
304
 
277
305
  **Components:** SmartTable, SmartFilter, EntityCard, SmartForm, StatCard (NEVER raw HTML)
278
- **CSS:** Variables ONLY — hardcoded Tailwind colors are **BLOCKING** in POST-CHECK 13:
306
+ **CSS:** Variables ONLY — hardcoded Tailwind colors are **BLOCKING** in POST-CHECK 9:
279
307
 
280
308
  | Instead of | Use |
281
309
  |-----------|-----|
@@ -375,7 +403,7 @@ t('{module}:actions.create', 'Create entity') // ALWAYS with namespace prefix
375
403
  | Action | Tool |
376
404
  |--------|------|
377
405
  | Generate doc-data.ts + page wrapper | `/documentation` skill (type: user) |
378
- | Verify DocToggleButton in pages | POST-CHECK 29 |
406
+ | Verify DocToggleButton in pages | POST-CHECK 24 |
379
407
 
380
408
  **Output files:**
381
409
  - `src/pages/docs/business/{app}/{module}/doc-data.ts` — data-driven documentation
@@ -400,3 +428,97 @@ See `references/smartstack-frontend.md` section 7 for the component pattern.
400
428
 
401
429
  **Target:** >= 80% coverage, 100% pass rate.
402
430
  **Fix CODE, not tests.**
431
+
432
+ ---
433
+
434
+ ## Planning Template — Per-File Plan Format
435
+
436
+ > **Used by step-02 when creating the execution plan.** Each entity MUST include:
437
+
438
+ ```yaml
439
+ Entity: {EntityName}
440
+ - tenantMode: strict | optional | scoped | none
441
+ - codePattern: auto-generated strategy (if applicable)
442
+ - fkFields: [{field, targetEntity}] (if applicable)
443
+ - acceptance criteria: [AC1, AC2, ...]
444
+ ```
445
+
446
+ For EACH file in the plan, specify HOW it will be created/modified:
447
+
448
+ **Layer 0 — Domain + Infrastructure (sequential):**
449
+
450
+ | # | File | Action | Tool |
451
+ |---|------|--------|------|
452
+ | 1 | Domain/Entities/.../Entity.cs | create | MCP scaffold_extension |
453
+ | 2 | Infrastructure/.../EntityConfiguration.cs | create | MCP scaffold_extension |
454
+ | 3 | Infrastructure/Migrations/ | create | MCP suggest_migration + dotnet ef |
455
+
456
+ **Layer 1 — Application + API + Seed Data (parallel):**
457
+
458
+ | # | File | Action | Tool |
459
+ |---|------|--------|------|
460
+ | 4 | Application/Services/.../Service.cs | create | MCP scaffold_extension |
461
+ | 5 | Application/DTOs/.../Dto.cs | create | MCP scaffold_extension |
462
+ | 6 | Api/Controllers/.../Controller.cs | create | /controller skill or MCP scaffold_extension |
463
+ | 7 | Seeding/Data/NavigationApplicationSeedData.cs | create | Reference Layer 1 Seed Data (once per app) |
464
+ | 7b | Seeding/Data/ApplicationRolesSeedData.cs | create | Reference Layer 1 Seed Data (once per app) |
465
+ | 7c | Infrastructure/Services/CodeGeneration/ | create | Reference code-generation.md (if codePattern != manual) |
466
+ | 8 | Seeding/Data/.../NavigationModuleSeedData.cs | create | Reference core-seed-data.md (4 langs) |
467
+ | 8b | Application/Authorization/Permissions.cs | create | MCP generate_permissions |
468
+ | 9 | Seeding/Data/.../PermissionsSeedData.cs | create | MCP generate_permissions |
469
+ | 10 | Seeding/Data/.../RolesSeedData.cs | create | Reference Layer 1 Seed Data |
470
+ | 10b | Seeding/{App}SeedDataProvider.cs | create | Reference core-seed-data.md (IClientSeedDataProvider + DI) |
471
+
472
+ **Layer 1 — Frontend (parallel):**
473
+
474
+ | # | File | Action | Tool |
475
+ |---|------|--------|------|
476
+ | 11 | src/pages/{App}/{Mod}/ListPage.tsx | create | /ui-components skill |
477
+ | 11b | src/pages/{App}/{Mod}/CreatePage.tsx | create | /ui-components skill (FK: EntityLookup) |
478
+ | 11c | src/pages/{App}/{Mod}/EditPage.tsx | create | /ui-components skill (FK: EntityLookup) |
479
+ | 12 | src/services/api/{module}Api.ts | create | MCP scaffold_api_client |
480
+ | 13 | src/routes/{module}.tsx | create | MCP scaffold_routes |
481
+ | 14 | src/i18n/locales/{lang}/{module}.json | create | Reference smartstack-frontend.md (4 languages) |
482
+
483
+ **Layer 2b — Documentation (after frontend):**
484
+
485
+ | # | File | Action | Tool |
486
+ |---|------|--------|------|
487
+ | 14b | src/pages/docs/business/{app}/{module}/doc-data.ts | create | /documentation skill |
488
+ | 14c | src/pages/docs/business/{app}/{module}/index.tsx | create | /documentation skill |
489
+
490
+ **Layer 3 — Tests (sequential):**
491
+
492
+ | # | File | Action | Tool |
493
+ |---|------|--------|------|
494
+ | 15 | tests/.../EntityTests.cs | create | MCP scaffold_tests |
495
+ | 16 | tests/.../ServiceTests.cs | create | MCP scaffold_tests |
496
+
497
+ **FK Field Guidance:** If step-01 identified `fkFields[]`, every Create/Edit page MUST use `EntityLookup` for those fields (see `smartstack-frontend.md` section 6).
498
+
499
+ ---
500
+
501
+ ## Parallelization Strategy (Agent Teams)
502
+
503
+ If NOT economy_mode AND Layer 1 has both backend and frontend work:
504
+
505
+ **Create agent teams to execute Layer 1 backend and frontend in parallel.**
506
+
507
+ See `references/agent-teams-protocol.md` for team creation, teammate spawning, task coordination, and shutdown.
508
+
509
+ ---
510
+
511
+ ## Delegate Mode Fast Path
512
+
513
+ When `/ralph-loop` invokes `/apex -d {prd_path}`, PRD tasks already define the scope.
514
+
515
+ Map each PRD task to a layer based on `task.category`:
516
+ - `domain` → Layer 0
517
+ - `infrastructure` → Layer 0
518
+ - `application` → Layer 1
519
+ - `api` → Layer 1
520
+ - `seedData` → Layer 1
521
+ - `frontend` → Layer 2
522
+ - `test` → Layer 3
523
+
524
+ For each task: infer file_path, action, and tool from category. SKIP user checkpoint. Jump to "Estimated Commits" section.
@@ -131,9 +131,9 @@ IF failure → warn user, continue in degraded mode (manual tools only)
131
131
 
132
132
  ## 4. Define Navigation Hierarchy (4 Levels)
133
133
 
134
- > **Reference:** Load `references/initialization-challenge-flow.md` for detailed challenge flow:
134
+ > **Reference:** Load `references/challenge-questions.md` for hierarchy rules and challenge questions:
135
135
  > - 4-level hierarchy structure (Application → Module → Section → Resource)
136
- > - Challenge questions (4a: Application, 4b: Module, 4c: Sections)
136
+ > - Challenge questions (4a: Application, 4b: Module, 4c: Sections, 5a: Entities, 5b: Dependencies)
137
137
  > - Validation rules (sections MUST have at least one entry)
138
138
  > - Storage format for each level
139
139
  > - Delegate mode skip (if -d)
@@ -13,6 +13,7 @@ next_step: steps/step-02-plan.md
13
13
  ## LOAD CONDITIONALLY
14
14
 
15
15
  - **ALWAYS** read `references/smartstack-api.md` — BaseEntity API, entity/config/controller patterns
16
+ > **CONTEXT NOTE:** This file stays in context and is reused by step-03. Do NOT re-read it there.
16
17
  - If NOT `{economy_mode}`: read `references/agent-teams-protocol.md`
17
18
 
18
19
  ---
@@ -12,7 +12,8 @@ next_step: steps/step-03-execute.md
12
12
 
13
13
  ## LOAD CONDITIONALLY
14
14
 
15
- Read `references/smartstack-layers.md` for layer execution rules and skill/MCP mapping.
15
+ Read `references/smartstack-layers.md` for layer execution rules, skill/MCP mapping, planning templates, and delegate mode fast path.
16
+ > **CONTEXT NOTE:** This file stays in context and is reused by step-03. Do NOT re-read it there.
16
17
 
17
18
  ---
18
19
 
@@ -54,11 +55,11 @@ IF delegate_mode:
54
55
 
55
56
  ## 1-3. Layer Mapping, Skill Assignment, Parallelization
56
57
 
57
- > **Reference:** Load `references/planning-layer-mapping.md` for detailed planning procedures:
58
+ > **Reference:** All planning procedures are now in `references/smartstack-layers.md` (already loaded above):
58
59
  > - Layer assignment matrix (Domain/Infrastructure/Application/API/Seed/Frontend/Tests)
59
60
  > - Entity definition template (tenantMode, codePattern, fkFields, ACs)
60
61
  > - Skill/MCP assignment table (per file, per layer)
61
- > - Layer 0/1/2b/3 file lists with tools
62
+ > - Layer 0/1/2b/3 file lists with tools (see "Planning Template" section)
62
63
  > - FK field guidance (EntityLookup + backend ?search= parameter)
63
64
  > - Parallelization strategy (Agent Teams for Layer 1 backend+frontend)
64
65
  > - Delegate mode fast path (PRD task mapping to layers)
@@ -13,9 +13,9 @@ All code goes through skills (/controller, /application, /ui-components, /efcore
13
13
 
14
14
  ## LOAD CONDITIONALLY
15
15
 
16
- - **ALWAYS** read `references/smartstack-api.md` BaseEntity API, entity/config/controller patterns
17
- - **ALWAYS** read `references/smartstack-frontend.md` — lazy loading, i18n, page structure, CSS variables
18
- - Read `references/smartstack-layers.md` for execution rules per layer
16
+ > **CONTEXT REUSE:** `smartstack-api.md` (loaded in step-01) and `smartstack-layers.md` (loaded in step-02) are already in context. Do NOT re-read them.
17
+
18
+ - **ALWAYS** read `references/smartstack-frontend.md` lazy loading, i18n, page structure, CSS variables, EntityLookup, compliance gates (sections 1-9)
19
19
  - If NOT `{economy_mode}` AND Layer 1 has parallel work: read `references/agent-teams-protocol.md`
20
20
  - If `{delegate_mode}` AND seedData tasks exist: read `references/core-seed-data.md` — comprehensive seed data templates
21
21
  - If build failure during execution: read `references/error-classification.md` — error diagnosis categories A-F
@@ -98,12 +98,12 @@ dotnet build
98
98
 
99
99
  ## Layer 1 — Application + API + Seed Data
100
100
 
101
- > **Reference:** Load `references/execution-layer1-rules.md` for critical Layer 1 rules:
102
- > - NavRoute and permission kebab-case (POST-CHECKs 41 + 48)
103
- > - Controller route attributes (POST-CHECK 50)
104
- > - Validators DI registration (POST-CHECK 46)
105
- > - DateOnly vs string (POST-CHECK 47)
106
- > - Code generation patterns (ICodeGenerator<T> registration)
101
+ > **Layer 1 rules** are in `references/smartstack-layers.md` (already in context from step-02):
102
+ > - NavRoute and permission kebab-case (Layer 1 - API section)
103
+ > - Controller route attributes (FORBIDDEN: [Route] alongside [NavRoute])
104
+ > - Validators DI registration
105
+ > - DateOnly vs string for DTO date fields
106
+ > - Code generation patterns (ICodeGenerator<T> registration, see references/code-generation.md)
107
107
 
108
108
  ### Backend Tasks (sequential or parallel)
109
109
 
@@ -114,17 +114,17 @@ dotnet build
114
114
 
115
115
  ### Frontend Tasks (sequential or parallel)
116
116
 
117
- > **Reference:** Load `references/execution-frontend-patterns.md` for complete frontend patterns:
117
+ > **Frontend patterns** are in `references/smartstack-frontend.md` (already loaded above):
118
118
  > - API client generation (MCP scaffold_api_client)
119
- > - Route scaffolding (MCP scaffold_routes)
120
- > - Page types (ListPage, DetailPage, CreatePage, EditPage)
121
- > - FK field handling (EntityLookup component)
122
- > - Form structure (ZERO modals — all full pages)
123
- > - Detail page tabs (local state only)
124
- > - Testing patterns (co-located form tests)
125
- > - Section-level routes and permissions
126
- > - Sub-resource handling
127
- > - I18n JSON structure and registration (POST-CHECK 45)
119
+ > - Route scaffolding (MCP scaffold_routes) — section 1 + 3b
120
+ > - Page types (ListPage, DetailPage, CreatePage, EditPage) — section 3
121
+ > - FK field handling (EntityLookup component) — section 6
122
+ > - Form structure (ZERO modals — all full pages) — section 3b
123
+ > - Detail page tabs (local state only) — section 3 "Tab Behavior Rules"
124
+ > - Testing patterns (co-located form tests) — section 8
125
+ > - Section-level routes and permissions — section 3b
126
+ > - I18n JSON structure and registration — section 2
127
+ > - Compliance gates (5 mandatory checks) section 9
128
128
 
129
129
  ### If NOT economy_mode: Agent Teams (parallel)
130
130
 
@@ -187,8 +187,8 @@ Spawn 2 teammates (Opus, full tools):
187
187
  → EntityEditPage.test.tsx (co-located next to page)
188
188
  → Cover: rendering, validation, submit, pre-fill, navigation, errors
189
189
  → See smartstack-frontend.md section 8 for test templates
190
- - **SECTION PERMISSIONS:** After MCP generate_permissions for the module navRoute (2 segments),
191
- also call MCP generate_permissions for EACH section navRoute (3 segments: {app}.{module}.{section})
190
+ - **PERMISSIONS:** Call MCP generate_permissions for the module permission root (2 segments: {app}.{module}),
191
+ then also call MCP generate_permissions for EACH section (3 segments: {app}.{module}.{section}).
192
192
  - **SECTION ROUTES:** Add section child routes to the module's children array.
193
193
  Wire PermissionGuard for section routes with section-level permissions.
194
194
  - I18n: Generate 4 JSON files per module namespace (fr, en, it, de)
@@ -253,7 +253,7 @@ After Layer 1 completes:
253
253
  ```
254
254
  1. Verify seed data completeness:
255
255
  - NavigationModuleSeedData.cs with 4 languages
256
- - PermissionsSeedData.cs with deterministic GUIDs
256
+ - PermissionsSeedData.cs with Guid.NewGuid()
257
257
  - RolesSeedData.cs with context-based role mapping
258
258
  - IClientSeedDataProvider updated
259
259
  - DI registration added
@@ -267,8 +267,8 @@ After Layer 1 completes:
267
267
 
268
268
  ## FRONTEND COMPLIANCE GATE (MANDATORY before commit)
269
269
 
270
- > **Reference:** Load `references/execution-frontend-gates.md` for all 5 mandatory checks:
271
- > 1. CSS Variables (theme system) — POST-CHECK 13
270
+ > **Reference:** See `references/smartstack-frontend.md` section 9 "Compliance Gates" for all 5 mandatory checks:
271
+ > 1. CSS Variables (theme system)
272
272
  > 2. Forms as Pages (ZERO modals/drawers/slide-overs)
273
273
  > 3. I18n File Structure (4 languages, separate JSON files)
274
274
  > 4. Lazy Loading (React.lazy() — no static imports)