@atlashub/smartstack-cli 3.8.0 → 3.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) 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 +211 -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/application-roles-template.md +227 -0
  28. package/templates/skills/application/references/backend-controller-hierarchy.md +58 -0
  29. package/templates/skills/application/references/backend-entity-seeding.md +72 -0
  30. package/templates/skills/application/references/backend-verification.md +88 -0
  31. package/templates/skills/application/references/frontend-verification.md +111 -0
  32. package/templates/skills/application/references/nav-fallback-procedure.md +200 -0
  33. package/templates/skills/application/references/provider-template.md +158 -0
  34. package/templates/skills/application/references/test-frontend.md +73 -0
  35. package/templates/skills/application/references/test-prerequisites.md +72 -0
  36. package/templates/skills/application/steps/step-01-navigation.md +7 -198
  37. package/templates/skills/application/steps/step-03-roles.md +45 -7
  38. package/templates/skills/application/steps/step-03b-provider.md +15 -132
  39. package/templates/skills/application/steps/step-04-backend.md +20 -350
  40. package/templates/skills/application/steps/step-05-frontend.md +12 -101
  41. package/templates/skills/application/steps/step-07-tests.md +12 -132
  42. package/templates/skills/business-analyse/SKILL.md +67 -6
  43. package/templates/skills/business-analyse/html/ba-interactive.html +176 -14
  44. package/templates/skills/business-analyse/html/src/scripts/01-data-init.js +1 -0
  45. package/templates/skills/business-analyse/html/src/scripts/05-render-specs.js +16 -4
  46. package/templates/skills/business-analyse/html/src/scripts/06-render-consolidation.js +7 -2
  47. package/templates/skills/business-analyse/html/src/scripts/09-export.js +103 -0
  48. package/templates/skills/business-analyse/html/src/scripts/10-comments.js +12 -6
  49. package/templates/skills/business-analyse/html/src/scripts/11-review-panel.js +24 -2
  50. package/templates/skills/business-analyse/html/src/styles/08-review-panel.css +12 -0
  51. package/templates/skills/business-analyse/html/src/template.html +1 -0
  52. package/templates/skills/business-analyse/references/agent-pooling-best-practices.md +477 -0
  53. package/templates/skills/business-analyse/references/cache-warming-strategy.md +578 -0
  54. package/templates/skills/business-analyse/references/cadrage-structure-cards.md +78 -0
  55. package/templates/skills/business-analyse/references/cadrage-vibe-coding.md +97 -0
  56. package/templates/skills/business-analyse/references/consolidation-structural-checks.md +92 -0
  57. package/templates/skills/business-analyse/references/deploy-data-build.md +121 -0
  58. package/templates/skills/business-analyse/references/deploy-modes.md +49 -0
  59. package/templates/skills/business-analyse/references/handoff-file-templates.md +119 -0
  60. package/templates/skills/business-analyse/references/handoff-mappings.md +81 -0
  61. package/templates/skills/business-analyse/references/html-data-mapping.md +10 -2
  62. package/templates/skills/business-analyse/references/init-schema-deployment.md +65 -0
  63. package/templates/skills/business-analyse/references/review-data-mapping.md +363 -0
  64. package/templates/skills/business-analyse/references/robustness-checks.md +538 -0
  65. package/templates/skills/business-analyse/references/spec-auto-inference.md +57 -0
  66. package/templates/skills/business-analyse/references/ui-dashboard-spec.md +85 -0
  67. package/templates/skills/business-analyse/references/ui-resource-cards.md +110 -0
  68. package/templates/skills/business-analyse/references/validate-incremental-html.md +55 -0
  69. package/templates/skills/business-analyse/schemas/sections/specification-schema.json +33 -1
  70. package/templates/skills/business-analyse/steps/step-00-init.md +186 -53
  71. package/templates/skills/business-analyse/steps/step-01-cadrage.md +5 -194
  72. package/templates/skills/business-analyse/steps/step-03a-data.md +42 -49
  73. package/templates/skills/business-analyse/steps/step-03b-ui.md +12 -178
  74. package/templates/skills/business-analyse/steps/step-03c-compile.md +71 -2
  75. package/templates/skills/business-analyse/steps/step-03d-validate.md +277 -48
  76. package/templates/skills/business-analyse/steps/step-04-consolidation.md +175 -104
  77. package/templates/skills/business-analyse/steps/step-05a-handoff.md +66 -438
  78. package/templates/skills/business-analyse/steps/step-05b-deploy.md +35 -184
  79. package/templates/skills/business-analyse/steps/step-05c-ralph-readiness.md +526 -0
  80. package/templates/skills/business-analyse/steps/step-06-review.md +277 -0
  81. package/templates/skills/cc-agent/references/agent-behavior-patterns.md +95 -0
  82. package/templates/skills/cc-agent/steps/step-02-generate.md +5 -78
  83. package/templates/skills/check-version/SKILL.md +7 -0
  84. package/templates/skills/controller/references/controller-code-templates.md +159 -0
  85. package/templates/skills/controller/references/permission-sync-templates.md +152 -0
  86. package/templates/skills/controller/steps/step-03-generate.md +166 -158
  87. package/templates/skills/controller/steps/step-04-perms.md +5 -144
  88. package/templates/skills/controller/templates.md +11 -2
  89. package/templates/skills/debug/SKILL.md +7 -0
  90. package/templates/skills/explore/SKILL.md +6 -0
  91. package/templates/skills/feature-full/SKILL.md +39 -142
  92. package/templates/skills/feature-full/steps/step-01-implementation.md +120 -0
  93. package/templates/skills/gitflow/references/init-config-template.md +135 -0
  94. package/templates/skills/gitflow/references/init-name-normalization.md +103 -0
  95. package/templates/skills/gitflow/references/plan-template.md +69 -0
  96. package/templates/skills/gitflow/references/start-efcore-preflight.md +70 -0
  97. package/templates/skills/gitflow/references/start-local-config.md +110 -0
  98. package/templates/skills/gitflow/steps/step-init.md +18 -289
  99. package/templates/skills/gitflow/steps/step-plan.md +6 -63
  100. package/templates/skills/gitflow/steps/step-start.md +16 -126
  101. package/templates/skills/mcp/SKILL.md +9 -213
  102. package/templates/skills/mcp/steps/step-01-healthcheck.md +108 -0
  103. package/templates/skills/mcp/steps/step-02-tools.md +73 -0
  104. package/templates/skills/notification/SKILL.md +7 -0
  105. package/templates/skills/quick-search/SKILL.md +5 -0
  106. package/templates/skills/ralph-loop/SKILL.md +99 -381
  107. package/templates/skills/ralph-loop/references/category-rules.md +259 -0
  108. package/templates/skills/ralph-loop/references/compact-loop.md +182 -0
  109. package/templates/skills/ralph-loop/references/core-seed-data.md +173 -21
  110. package/templates/skills/ralph-loop/references/task-transform-legacy.md +259 -0
  111. package/templates/skills/ralph-loop/references/team-orchestration.md +189 -0
  112. package/templates/skills/ralph-loop/steps/step-00-init.md +111 -383
  113. package/templates/skills/ralph-loop/steps/step-01-task.md +79 -896
  114. package/templates/skills/ralph-loop/steps/step-02-execute.md +68 -680
  115. package/templates/skills/ralph-loop/steps/step-03-commit.md +47 -277
  116. package/templates/skills/ralph-loop/steps/step-04-check.md +124 -607
  117. package/templates/skills/ralph-loop/steps/step-05-report.md +68 -367
  118. package/templates/skills/refactor/SKILL.md +12 -176
  119. package/templates/skills/refactor/steps/step-01-discover.md +60 -0
  120. package/templates/skills/refactor/steps/step-02-execute.md +67 -0
  121. package/templates/skills/review-code/SKILL.md +19 -257
  122. package/templates/skills/review-code/steps/step-01-smartstack.md +96 -0
  123. package/templates/skills/review-code/steps/step-02-detailed-review.md +80 -0
  124. package/templates/skills/review-code/steps/step-03-react.md +44 -0
  125. package/templates/skills/ui-components/SKILL.md +7 -0
  126. package/templates/skills/utils/SKILL.md +6 -0
  127. package/templates/skills/validate/SKILL.md +6 -0
  128. package/templates/skills/validate-feature/SKILL.md +8 -0
  129. package/templates/skills/workflow/SKILL.md +40 -118
  130. package/templates/skills/workflow/steps/step-01-implementation.md +84 -0
@@ -0,0 +1,58 @@
1
+ # Controller NavRoute and Folder Hierarchy
2
+
3
+ > Referenced from `steps/step-04-backend.md` — Controller file organization and NavRoute conventions.
4
+
5
+ ---
6
+
7
+ ## Controller File Location
8
+
9
+ Controllers are organized by **context short name** and **application** (matching SmartStack.app pattern):
10
+
11
+ ```
12
+ Api/Controllers/
13
+ ├── Admin/ ← platform.administration
14
+ │ ├── {Application}/ ← Application sub-folder (e.g., AI/, Communications/, Tenants/)
15
+ │ │ └── {EntityName}Controller.cs
16
+ │ └── {EntityName}Controller.cs ← Direct controllers (no application sub-folder)
17
+ ├── Business/ ← business.*
18
+ │ └── {EntityName}Controller.cs
19
+ ├── Support/ ← platform.support
20
+ │ └── {EntityName}Controller.cs
21
+ ├── User/ ← personal.*
22
+ │ └── {EntityName}Controller.cs
23
+ └── {SharedControllers}.cs ← Root-level (Auth, Config, Navigation, etc.)
24
+ ```
25
+
26
+ ## Context-to-Folder Mapping
27
+
28
+ | NavRoute Context | Controller Folder | Example |
29
+ |-----------------|-------------------|---------|
30
+ | `platform.administration` | `Admin` | `Controllers/Admin/TenantsController.cs` |
31
+ | `platform.administration.{app}` | `Admin/{App}` | `Controllers/Admin/AI/AiPromptsController.cs` |
32
+ | `platform.support` | `Support` | `Controllers/Support/TicketsController.cs` |
33
+ | `business.*` | `Business` | `Controllers/Business/MyTicketsController.cs` |
34
+ | `personal.*` | `User` | `Controllers/User/PreferencesController.cs` |
35
+
36
+ ## Controller Attributes
37
+
38
+ The generated controller uses NavRoute attribute:
39
+
40
+ ```csharp
41
+ [NavRoute("{full_path}")]
42
+ [ApiController]
43
+ [Authorize]
44
+ public class {EntityName}Controller : ControllerBase
45
+ {
46
+ [HttpGet]
47
+ [RequirePermission(Permissions.{Context}.{Application}.{Module}.Read)]
48
+ public async Task<ActionResult<IEnumerable<{EntityName}Dto>>> GetAll() { ... }
49
+
50
+ // ... other CRUD methods
51
+ }
52
+ ```
53
+
54
+ This ensures:
55
+ - API route is derived from navigation path
56
+ - Permissions use the constants from Permissions.cs
57
+ - Frontend can discover API path from NavRoute registry
58
+ - Controller file is in the correct context/application folder
@@ -0,0 +1,72 @@
1
+ # Entity Seeding Pattern
2
+
3
+ > Reference: See `templates-seed.md` section "TEMPLATE: ENTITY SEED DATA (SeedData Provider)"
4
+
5
+ ## SeedData File
6
+
7
+ **`Infrastructure/Persistence/Seeding/Data/{Domain}/{EntityName}SeedData.cs`**
8
+
9
+ Follow SmartStack.app pattern:
10
+ - Static class with `internal static IEnumerable<{EntityName}SeedItem> GetAll{EntityName}s()`
11
+ - Use deterministic GUIDs (NEVER `Guid.NewGuid()`)
12
+ - Include 3-5 sample entities with varied, realistic data
13
+ - For multi-tenant: organize by tenant using `GetTenant1{EntityName}s()` helpers
14
+
15
+ ```csharp
16
+ public static class {EntityName}SeedData
17
+ {
18
+ public static readonly Guid Sample1Id = Guid.Parse("...");
19
+ public static readonly Guid Sample2Id = Guid.Parse("...");
20
+ public static readonly Guid Sample3Id = Guid.Parse("...");
21
+
22
+ internal static IEnumerable<{EntityName}SeedItem> GetAll{EntityName}s()
23
+ {
24
+ return new[]
25
+ {
26
+ new {EntityName}SeedItem { Id = Sample1Id, /* ... */ },
27
+ new {EntityName}SeedItem { Id = Sample2Id, /* ... */ },
28
+ new {EntityName}SeedItem { Id = Sample3Id, /* ... */ }
29
+ };
30
+ }
31
+ }
32
+
33
+ internal class {EntityName}SeedItem
34
+ {
35
+ public Guid Id { get; init; }
36
+ // ... all required entity properties
37
+ }
38
+ ```
39
+
40
+ ## DevDataSeeder Update
41
+
42
+ Add to `Infrastructure/Persistence/Seeding/DevDataSeeder.cs`:
43
+ - `using` for the new SeedData namespace
44
+ - `await Seed{EntityName}sAsync(cancellationToken);` in `SeedAsync()` method
45
+
46
+ ```csharp
47
+ private async Task Seed{EntityName}sAsync(CancellationToken cancellationToken)
48
+ {
49
+ _logger.LogInformation("Seeding demo {EntityName}s...");
50
+
51
+ var existingCount = await _context.{EntityName}s.CountAsync(cancellationToken);
52
+ if (existingCount > 0)
53
+ {
54
+ _logger.LogWarning("{EntityName}s already seeded ({Count} exist), skipping.", existingCount);
55
+ return;
56
+ }
57
+
58
+ var createdCount = 0;
59
+ foreach (var seedItem in {EntityName}SeedData.GetAll{EntityName}s())
60
+ {
61
+ var entity = {EntityName}.Create(/* map seedItem properties */);
62
+ typeof({EntityName}).GetProperty("Id")?.SetValue(entity, seedItem.Id);
63
+ _context.{EntityName}s.Add(entity);
64
+ createdCount++;
65
+ }
66
+
67
+ if (createdCount > 0)
68
+ await _context.SaveChangesAsync(cancellationToken);
69
+
70
+ _logger.LogInformation("Created {Count} demo {EntityName}s.", createdCount);
71
+ }
72
+ ```
@@ -0,0 +1,88 @@
1
+ # Backend Post-Generation Verification
2
+
3
+ **Run ALL checks before proceeding to next step.**
4
+
5
+ ## Check 1: Backend Build (BLOCKING)
6
+
7
+ ```bash
8
+ dotnet build {SolutionName}.sln --no-restore
9
+ ```
10
+
11
+ IF build fails: Read errors, fix compilation issues, re-run until success.
12
+
13
+ ## Check 2: DbSet Registration (BLOCKING)
14
+
15
+ Search for `DbSet<{EntityName}>` in `I{DbContextName}.cs` or `{DbContextName}.cs`.
16
+
17
+ IF NOT found, add:
18
+ ```csharp
19
+ public DbSet<{EntityName}> {EntityName}s => Set<{EntityName}>();
20
+ ```
21
+
22
+ ## Check 3: DI Registration (BLOCKING)
23
+
24
+ Search for `I{EntityName}Service` in `DependencyInjection.cs`.
25
+
26
+ IF NOT found, add:
27
+ ```csharp
28
+ services.AddScoped<I{EntityName}Service, {EntityName}Service>();
29
+ ```
30
+
31
+ ## Check 4: RequirePermission Attributes (BLOCKING)
32
+
33
+ Each HTTP action MUST have `[RequirePermission(Permissions.{Context}.{Application}.{Module}.{Action})]`.
34
+
35
+ ## Check 5: Entity Configuration (BLOCKING)
36
+
37
+ Verify:
38
+ - `builder.ToTable("{table_prefix}{EntityName}s")` uses correct prefix
39
+ - `builder.HasKey(e => e.Id)` present
40
+ - `builder.HasIndex` for unique fields
41
+
42
+ ## Check 5b: Seeding Infrastructure (first entity only)
43
+
44
+ **If this is the FIRST entity (no existing DevDataSeeder):**
45
+
46
+ 1. **`Infrastructure/Persistence/Seeding/Data/SeedConstants.cs`**
47
+ ```csharp
48
+ namespace {BaseNamespace}.Infrastructure.Persistence.Seeding.Data;
49
+ public static class SeedConstants
50
+ {
51
+ public static readonly DateTime SeedDate = new(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc);
52
+ }
53
+ ```
54
+
55
+ 2. **`Infrastructure/Persistence/Seeding/DevDataSeeder.cs`**
56
+ ```csharp
57
+ public class DevDataSeeder : IDevDataSeeder
58
+ {
59
+ private readonly ExtensionsDbContext _context;
60
+ private readonly ILogger<DevDataSeeder> _logger;
61
+ public DevDataSeeder(ExtensionsDbContext context, ILogger<DevDataSeeder> logger) { _context = context; _logger = logger; }
62
+ public async Task SeedAsync(CancellationToken cancellationToken = default)
63
+ {
64
+ _logger.LogInformation("Starting development data seeding...");
65
+ // Add Seed{Entity}sAsync calls here
66
+ _logger.LogInformation("Development data seeding complete.");
67
+ }
68
+ }
69
+ ```
70
+
71
+ 3. Register: `services.AddScoped<IDevDataSeeder, DevDataSeeder>();`
72
+
73
+ ## Check 5c: SqlObjects Directory (first entity only)
74
+
75
+ **If no existing SqlObjectHelper:**
76
+
77
+ 1. **`Infrastructure/Persistence/SqlObjects/SqlObjectHelper.cs`** - Helper for embedded SQL resources
78
+ 2. Create `Infrastructure/Persistence/SqlObjects/Functions/` directory
79
+ 3. Ensure `.csproj` has: `<EmbeddedResource Include="Persistence\SqlObjects\**\*.sql" />`
80
+
81
+ ## Check 6: Convention Validation (RECOMMENDED)
82
+
83
+ ```
84
+ Tool: mcp__smartstack__validate_conventions
85
+ Args: target: "backend", scope: "{entity_name}"
86
+ ```
87
+
88
+ Verifies naming conventions, architecture layers, required attributes, DTO patterns.
@@ -0,0 +1,111 @@
1
+ # Frontend: Routing Rules & Post-Generation Verification
2
+
3
+ > Reference for step-05-frontend.md — routing rules and mandatory verification checks.
4
+
5
+ ## Routing Rules
6
+
7
+ ### Rule 1: Routes MUST be inside Layout wrappers
8
+
9
+ **CRITICAL:** All routes MUST be nested inside the appropriate context layout. This is what provides the SmartStack shell (header with AvatarMenu, sidebar, navigation).
10
+
11
+ ```tsx
12
+ // CORRECT - Inside BusinessLayout (shell renders: header + AvatarMenu + sidebar)
13
+ <Route path="/business" element={<BusinessLayout />}>
14
+ <Route path="sales/products" element={<ProductsPage />} />
15
+ </Route>
16
+
17
+ // FORBIDDEN - Outside layout (NO shell, NO header, NO AvatarMenu!)
18
+ <Route path="/business/sales/products" element={<ProductsPage />} />
19
+ ```
20
+
21
+ ### Rule 2: Use nested routes (not flat)
22
+
23
+ **CRITICAL:** SmartStack requires NESTED routes within the layout:
24
+
25
+ ```tsx
26
+ // CORRECT - Nested routes inside layout
27
+ <Route path="/business" element={<BusinessLayout />}>
28
+ <Route path="sales">
29
+ <Route index element={<Navigate to="products" replace />} />
30
+ <Route path="products" element={<ProductsPage />} />
31
+ <Route path="orders" element={<OrdersPage />} />
32
+ </Route>
33
+ </Route>
34
+
35
+ // FORBIDDEN - Flat routes (cause redirect issues + bypass layout)
36
+ <Route path="/business/sales" element={<Navigate to="products" />} />
37
+ <Route path="/business/sales/products" element={<ProductsPage />} />
38
+ ```
39
+
40
+ ## Post-Generation Verification (MANDATORY)
41
+
42
+ **Before proceeding to step-06, run these checks on ALL generated frontend files:**
43
+
44
+ ### 1. CSS Variables Check (BLOCKING)
45
+
46
+ Scan all generated `.tsx` files for hardcoded Tailwind colors:
47
+
48
+ ```
49
+ FORBIDDEN patterns: bg-blue-, bg-red-, bg-green-, bg-gray-, bg-amber-,
50
+ text-blue-, text-red-, text-green-, text-gray-, text-amber-,
51
+ border-blue-, border-red-, border-green-, border-gray-
52
+ ```
53
+
54
+ If ANY hardcoded color is found → **FIX IT** using CSS variables from style-guide.md before continuing.
55
+
56
+ ### 2. API Client Check (BLOCKING)
57
+
58
+ Verify all API service files use the configured client:
59
+ - **CORRECT:** `import { api } from '@/services/api/apiClient'` or `import api from '../api'`
60
+ - **FORBIDDEN:** `import axios from 'axios'`
61
+
62
+ ### 3. EntityCard Check
63
+
64
+ If a grid/card view is generated, verify it uses `EntityCard` component (not custom divs).
65
+
66
+ ### 4. i18n Check (BLOCKING)
67
+
68
+ Verify exactly **4 language files** exist with identical key structures:
69
+ - `fr/{entityCode}.json`
70
+ - `en/{entityCode}.json`
71
+ - `it/{entityCode}.json`
72
+ - `de/{entityCode}.json`
73
+
74
+ ### 5. Route Check (BLOCKING)
75
+
76
+ Verify routes are:
77
+ - **INSIDE** the Layout wrapper (`BusinessLayout`, `AdminLayout`, or `UserLayout`)
78
+ - **NESTED** (not flat)
79
+ - Following path convention: `/{context}/{application}/{module}`
80
+
81
+ ### 6. States Check
82
+
83
+ Verify the list page includes:
84
+ - Loading state (spinner)
85
+ - Error state (icon + message + retry button)
86
+ - Empty state (icon + message)
87
+
88
+ ### 7. TypeScript Build Check (BLOCKING)
89
+
90
+ Run the frontend type check to verify all generated files compile:
91
+
92
+ ```bash
93
+ cd web && npx tsc --noEmit 2>&1 | head -50
94
+ ```
95
+
96
+ OR if the project uses a build script:
97
+
98
+ ```bash
99
+ cd web && npm run build 2>&1 | head -80
100
+ ```
101
+
102
+ IF type errors exist **in generated files**: Fix them before proceeding.
103
+ Common issues: missing imports, wrong interface names, incorrect prop types, missing hook return types.
104
+
105
+ IF type errors exist **in other pre-existing files**: NON-BLOCKING. Note them but proceed.
106
+
107
+ **Focus only on errors in files generated by this step:**
108
+ - `pages/{context}/{application}/{module}/*.tsx`
109
+ - `services/api/{entityCode}Api.ts`
110
+ - `types/{entityName}.types.ts`
111
+ - `hooks/use{EntityName}*.ts`
@@ -0,0 +1,200 @@
1
+ # Navigation: Fallback Procedure (When MCP Unavailable)
2
+
3
+ > Reference for step-01-navigation.md — generates navigation seeds following SmartStack.app patterns.
4
+ > Reference: `templates-seed.md` for code templates.
5
+ >
6
+ > **Branch by Project Type:**
7
+ > - If `{seeding_strategy}` = "hasdata" (core project): Follow F1-F8 below
8
+ > - If `{seeding_strategy}` = "provider" (client project): Follow **CLIENT PROJECT HANDLING** in step file
9
+
10
+ ## F1. Read Existing Configuration Files
11
+
12
+ **CRITICAL:** Before generating any code, read existing files to determine state:
13
+
14
+ 1. **Find the Navigation Configuration directory:**
15
+ ```
16
+ Glob: **/Persistence/Configurations/Navigation/Navigation*Configuration.cs
17
+ ```
18
+
19
+ 2. **Read NavigationTranslationConfiguration.cs** - Find the last GUID index:
20
+ ```
21
+ Search for: the last call to GenerateGuid(index++)
22
+ The index variable starts at 1 and increments per translation entry.
23
+ Your new translations MUST continue from the next index value.
24
+ ```
25
+
26
+ 3. **Read Navigation{Level}Configuration.cs** - Check existing entities:
27
+ ```
28
+ Read the Configuration for the target level (Context, Application, Module, Section).
29
+ Check if it already references a SeedData class: builder.HasData(Navigation{Level}SeedData.GetSeedData())
30
+ If yes: Read the corresponding SeedData class to find existing entries.
31
+ If no: You will need to add HasData() call.
32
+ ```
33
+
34
+ 4. **Read existing SeedData files** (if they exist):
35
+ ```
36
+ Glob: **/Seeding/Data/Navigation/Navigation{Level}SeedData.cs
37
+ Check for existing entity IDs to avoid collisions.
38
+ ```
39
+
40
+ ## F2. Determine Parent GUID
41
+
42
+ For non-context levels, find the parent entity GUID:
43
+
44
+ | Level | Parent | Where to Find Parent GUID |
45
+ |-------|--------|---------------------------|
46
+ | application | context | `NavigationContextSeedData.cs` → e.g. `PlatformContextId` |
47
+ | module | application | `NavigationApplicationSeedData.cs` → e.g. `AdministrationAppId` |
48
+ | section | module | `NavigationModuleSeedData.cs` → e.g. `UsersModuleId` |
49
+
50
+ Read the parent SeedData class and find the GUID matching `{parent_path}`.
51
+
52
+ ## F3. Generate Navigation Entity GUID
53
+
54
+ Generate a deterministic GUID for the new navigation entity:
55
+
56
+ ```csharp
57
+ // Use SHA256 hash of the full_path for deterministic generation
58
+ using var sha256 = System.Security.Cryptography.SHA256.Create();
59
+ var hash = sha256.ComputeHash(Encoding.UTF8.GetBytes("navigation-{level}-{full_path}"));
60
+ var guid = new Guid(hash.Take(16).ToArray());
61
+ ```
62
+
63
+ **Rules:**
64
+ - NEVER use `Guid.NewGuid()`
65
+ - Read existing SeedData GUIDs to verify no collision
66
+ - Store result as `{navigation_guid}`
67
+
68
+ ## F4. Write Navigation Entity Seed
69
+
70
+ Based on `{level}`, write the seed entry.
71
+
72
+ **Option A: Project uses SeedData classes (SmartStack.app pattern)**
73
+
74
+ If `Navigation{Level}SeedData.cs` exists, add the new entity:
75
+
76
+ ```csharp
77
+ // In Infrastructure/Persistence/Seeding/Data/Navigation/Navigation{Level}SeedData.cs
78
+
79
+ // Add static GUID field
80
+ public static readonly Guid {PascalCode}Id = Guid.Parse("{navigation_guid}");
81
+
82
+ // Add to GetSeedData() return array
83
+ new {
84
+ Id = {PascalCode}Id,
85
+ ParentFk = Navigation{ParentLevel}SeedData.{ParentPascalCode}Id, // FK varies by level
86
+ Code = "{code}",
87
+ Label = "{labels.en}",
88
+ Description = "{descriptions.en}",
89
+ Icon = "{icon}",
90
+ IconType = IconType.Lucide,
91
+ Route = "/{full_path_with_slashes}",
92
+ DisplayOrder = {display_order},
93
+ IsActive = true,
94
+ CreatedAt = SeedConstants.SeedDate
95
+ }
96
+ ```
97
+
98
+ **FK property by level:**
99
+
100
+ | Level | FK Property | References |
101
+ |-------|-------------|------------|
102
+ | context | (none) | - |
103
+ | application | `ContextId` | NavigationContextSeedData.{Parent}Id |
104
+ | module | `ApplicationId` | NavigationApplicationSeedData.{Parent}Id |
105
+ | section | `ModuleId` | NavigationModuleSeedData.{Parent}Id |
106
+
107
+ **Option B: Project uses inline HasData**
108
+
109
+ If no SeedData class exists, add directly to `Navigation{Level}Configuration.cs`:
110
+
111
+ ```csharp
112
+ // In Configure method, add:
113
+ builder.HasData(new {
114
+ Id = Guid.Parse("{navigation_guid}"),
115
+ // ... same properties as Option A
116
+ });
117
+ ```
118
+
119
+ ## F5. Write Translation Entries
120
+
121
+ Add 4 translation entries to `NavigationTranslationConfiguration.cs`:
122
+
123
+ 1. Read the file to find the current highest `index` value
124
+ 2. Continue from `index + 1`
125
+ 3. Use the SAME `GenerateGuid` method already defined in the file:
126
+
127
+ ```csharp
128
+ // In GetSeedData() method, add at the end before return:
129
+
130
+ // {level}: {code} translations
131
+ translations.Add(new {
132
+ Id = GenerateGuid(index++),
133
+ EntityType = NavigationEntityType.{Level},
134
+ EntityId = Navigation{Level}SeedData.{PascalCode}Id, // or Guid.Parse("{navigation_guid}")
135
+ LanguageCode = "fr",
136
+ Label = "{labels.fr}",
137
+ Description = "{descriptions.fr}",
138
+ CreatedAt = seedDate
139
+ });
140
+ translations.Add(new {
141
+ Id = GenerateGuid(index++),
142
+ EntityType = NavigationEntityType.{Level},
143
+ EntityId = Navigation{Level}SeedData.{PascalCode}Id,
144
+ LanguageCode = "en",
145
+ Label = "{labels.en}",
146
+ Description = "{descriptions.en}",
147
+ CreatedAt = seedDate
148
+ });
149
+ translations.Add(new {
150
+ Id = GenerateGuid(index++),
151
+ EntityType = NavigationEntityType.{Level},
152
+ EntityId = Navigation{Level}SeedData.{PascalCode}Id,
153
+ LanguageCode = "it",
154
+ Label = "{labels.it}",
155
+ Description = "{descriptions.it}",
156
+ CreatedAt = seedDate
157
+ });
158
+ translations.Add(new {
159
+ Id = GenerateGuid(index++),
160
+ EntityType = NavigationEntityType.{Level},
161
+ EntityId = Navigation{Level}SeedData.{PascalCode}Id,
162
+ LanguageCode = "de",
163
+ Label = "{labels.de}",
164
+ Description = "{descriptions.de}",
165
+ CreatedAt = seedDate
166
+ });
167
+ ```
168
+
169
+ ## F6. Store Result
170
+
171
+ ```
172
+ {navigation_guid} = [generated GUID]
173
+ {seed_method} = "fallback" // Indicates MCP was not used
174
+ ```
175
+
176
+ ## F7. Validation Checklist
177
+
178
+ Before proceeding, verify:
179
+ - [ ] Deterministic GUID generated (not NewGuid())
180
+ - [ ] 4 languages present (fr, en, it, de)
181
+ - [ ] Translation index continues existing sequence (no gaps, no collisions)
182
+ - [ ] Parent GUID correctly references existing entity
183
+ - [ ] Route path matches `/{context}/{app}/{module}` pattern
184
+ - [ ] DisplayOrder is consistent with existing entities
185
+ - [ ] Code is WRITTEN to files, not just displayed
186
+
187
+ ## F8. Present Summary
188
+
189
+ ```markdown
190
+ ## Navigation Seeds Generated (Fallback)
191
+
192
+ **Entity:** {level} - {code}
193
+ **GUID:** {navigation_guid}
194
+ **Path:** {full_path}
195
+
196
+ ### Files Updated
197
+
198
+ 1. **Navigation{Level}SeedData.cs** (or Configuration.cs) - New entity entry
199
+ 2. **NavigationTranslationConfiguration.cs** - 4 translation entries added
200
+ ```
@@ -0,0 +1,158 @@
1
+ # IClientSeedDataProvider Template
2
+
3
+ > Referenced from `steps/step-03b-provider.md` — C# template for client project seed data providers.
4
+
5
+ ---
6
+
7
+ ## Provider Class Template
8
+
9
+ **Location:** `Infrastructure/Persistence/Seeding/{AppPascalName}SeedDataProvider.cs`
10
+
11
+ Where `{AppPascalName}` is derived from the application code (e.g., `free-bike` → `FreeBike`).
12
+
13
+ ```csharp
14
+ using Microsoft.EntityFrameworkCore;
15
+ using SmartStack.Application.Common.Interfaces;
16
+ using SmartStack.Domain.Navigation;
17
+ using SmartStack.Domain.Platform.Administration.Roles;
18
+
19
+ namespace {BaseNamespace}.Infrastructure.Persistence.Seeding;
20
+
21
+ /// <summary>
22
+ /// Seeds {AppLabel} navigation, roles, permissions, and role-permission data
23
+ /// into the SmartStack Core schema at application startup.
24
+ /// Implements <see cref="IClientSeedDataProvider"/> for runtime seeding
25
+ /// (no Core migrations required).
26
+ /// </summary>
27
+ public class {AppPascalName}SeedDataProvider : IClientSeedDataProvider
28
+ {
29
+ public int Order => 100;
30
+
31
+ public async Task SeedNavigationAsync(ICoreDbContext context, CancellationToken ct)
32
+ {
33
+ // Check idempotence
34
+ var exists = await context.NavigationApplications
35
+ .AnyAsync(a => a.Code == "{app_code}", ct);
36
+ if (exists) return;
37
+
38
+ // 1. Retrieve the parent context ("business", "platform", etc.)
39
+ var parentContext = await context.NavigationContexts
40
+ .FirstAsync(c => c.Code == "{context_code}", ct);
41
+
42
+ // 2. Create the application
43
+ var app = NavigationApplication.Create(
44
+ parentContext.Id,
45
+ "{app_code}",
46
+ "{app_label_en}",
47
+ "{app_desc_en}",
48
+ "{app_icon}",
49
+ IconType.Lucide,
50
+ "/{context_code}/{app_code}",
51
+ {display_order});
52
+ context.NavigationApplications.Add(app);
53
+ await ((DbContext)context).SaveChangesAsync(ct);
54
+
55
+ // 3. Create modules
56
+ // Use GUIDs and data from {Module}NavigationSeedData.cs
57
+ foreach (var moduleData in GetModuleSeedEntries(app.Id))
58
+ {
59
+ var module = NavigationModule.Create(
60
+ moduleData.ApplicationId,
61
+ moduleData.Code,
62
+ moduleData.Label,
63
+ moduleData.Description,
64
+ moduleData.Icon,
65
+ IconType.Lucide,
66
+ moduleData.Route,
67
+ moduleData.DisplayOrder);
68
+ context.NavigationModules.Add(module);
69
+ }
70
+ await ((DbContext)context).SaveChangesAsync(ct);
71
+
72
+ // 4. Create translations (4 languages per entity)
73
+ // Use data from {Module}NavigationTranslationSeedData.cs
74
+ // ...
75
+ await ((DbContext)context).SaveChangesAsync(ct);
76
+ }
77
+
78
+ public async Task SeedRolesAsync(ICoreDbContext context, CancellationToken ct)
79
+ {
80
+ // Check idempotence
81
+ var applicationId = ApplicationRolesSeedData.ApplicationId;
82
+ var exists = await context.Roles
83
+ .AnyAsync(r => r.ApplicationId == applicationId, ct);
84
+ if (exists) return;
85
+
86
+ // Create application-scoped roles (Admin, Manager, Contributor, Viewer)
87
+ // Use data from ApplicationRolesSeedData.cs
88
+ foreach (var entry in ApplicationRolesSeedData.GetRoleEntries())
89
+ {
90
+ var role = Role.Create(
91
+ entry.Code,
92
+ entry.Name,
93
+ entry.Description,
94
+ entry.ApplicationId,
95
+ entry.IsSystem);
96
+ context.Roles.Add(role);
97
+ }
98
+ await ((DbContext)context).SaveChangesAsync(ct);
99
+ }
100
+
101
+ public async Task SeedPermissionsAsync(ICoreDbContext context, CancellationToken ct)
102
+ {
103
+ // Check idempotence
104
+ var exists = await context.Permissions
105
+ .AnyAsync(p => p.Path == "{full_path}.*", ct);
106
+ if (exists) return;
107
+
108
+ // Retrieve modules by Code for FK resolution
109
+ // Use data from {Module}PermissionSeedData.cs
110
+ // Create via Permission.CreateForModule(...) and Permission.CreateWildcard(...)
111
+ // ...
112
+ await ((DbContext)context).SaveChangesAsync(ct);
113
+ }
114
+
115
+ public async Task SeedRolePermissionsAsync(ICoreDbContext context, CancellationToken ct)
116
+ {
117
+ // Check idempotence
118
+ var exists = await context.RolePermissions
119
+ .AnyAsync(rp => rp.Permission!.Path.StartsWith("{full_path}."), ct);
120
+ if (exists) return;
121
+
122
+ // Retrieve existing roles and created permissions
123
+ // Use data from {Module}RolePermissionSeedData.cs
124
+ // Create via RolePermission.Create(roleId, permissionId, "system")
125
+ // ...
126
+ await ((DbContext)context).SaveChangesAsync(ct);
127
+ }
128
+
129
+ // Private helper methods fed by SeedData classes
130
+ // ...
131
+ }
132
+ ```
133
+
134
+ ---
135
+
136
+ ## DI Registration
137
+
138
+ Modify `Infrastructure/DependencyInjection.cs` of the client project:
139
+
140
+ ```csharp
141
+ // Add using:
142
+ using SmartStack.Application.Common.Interfaces;
143
+
144
+ // In the registration method:
145
+ services.AddScoped<IClientSeedDataProvider, {AppPascalName}SeedDataProvider>();
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Critical Rules
151
+
152
+ 1. **Factory methods mandatory**: `NavigationModule.Create(...)`, `Role.Create(...)`, `Permission.CreateForModule(...)`, `RolePermission.Create(...)` — NEVER `new Entity()`
153
+ 2. **Idempotence**: Each Seed method checks existence before inserting
154
+ 3. **SaveChangesAsync per group**: Navigation → save → Roles → save → Permissions → save → RolePermissions → save
155
+ 4. **Execution order**: `SeedRolesAsync()` MUST be called BEFORE `SeedRolePermissionsAsync()` (roles must exist before mapping)
156
+ 5. **Deterministic GUIDs**: Use IDs from SeedData classes (not `Guid.NewGuid()`)
157
+ 6. **Resolve FK by Code**: Parent modules and roles are found by `Code`, not hardcoded GUID
158
+ 7. **Order property**: Use `100` as default. If multiple providers exist, they run in Order sequence