@atlashub/smartstack-cli 3.7.0 → 3.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/dist/index.js +365 -2
  2. package/dist/index.js.map +1 -1
  3. package/package.json +4 -2
  4. package/templates/agents/action.md +1 -0
  5. package/templates/agents/ba-writer.md +33 -0
  6. package/templates/agents/explore-codebase.md +1 -0
  7. package/templates/agents/explore-docs.md +1 -0
  8. package/templates/agents/fix-grammar.md +1 -0
  9. package/templates/agents/snipper.md +1 -0
  10. package/templates/skills/admin/SKILL.md +6 -0
  11. package/templates/skills/ai-prompt/SKILL.md +32 -136
  12. package/templates/skills/ai-prompt/steps/step-01-implementation.md +122 -0
  13. package/templates/skills/apex/SKILL.md +120 -0
  14. package/templates/skills/apex/_shared.md +86 -0
  15. package/templates/skills/apex/references/agent-teams-protocol.md +164 -0
  16. package/templates/skills/apex/references/smartstack-layers.md +173 -0
  17. package/templates/skills/apex/steps/step-00-init.md +156 -0
  18. package/templates/skills/apex/steps/step-01-analyze.md +169 -0
  19. package/templates/skills/apex/steps/step-02-plan.md +160 -0
  20. package/templates/skills/apex/steps/step-03-execute.md +166 -0
  21. package/templates/skills/apex/steps/step-04-validate.md +138 -0
  22. package/templates/skills/apex/steps/step-05-examine.md +124 -0
  23. package/templates/skills/apex/steps/step-06-resolve.md +105 -0
  24. package/templates/skills/apex/steps/step-07-tests.md +130 -0
  25. package/templates/skills/apex/steps/step-08-run-tests.md +115 -0
  26. package/templates/skills/application/SKILL.md +10 -0
  27. package/templates/skills/application/references/backend-controller-hierarchy.md +58 -0
  28. package/templates/skills/application/references/backend-entity-seeding.md +72 -0
  29. package/templates/skills/application/references/backend-verification.md +88 -0
  30. package/templates/skills/application/references/frontend-verification.md +111 -0
  31. package/templates/skills/application/references/nav-fallback-procedure.md +200 -0
  32. package/templates/skills/application/references/provider-template.md +134 -0
  33. package/templates/skills/application/references/test-frontend.md +73 -0
  34. package/templates/skills/application/references/test-prerequisites.md +72 -0
  35. package/templates/skills/application/steps/step-01-navigation.md +7 -198
  36. package/templates/skills/application/steps/step-03b-provider.md +4 -128
  37. package/templates/skills/application/steps/step-04-backend.md +20 -350
  38. package/templates/skills/application/steps/step-05-frontend.md +12 -101
  39. package/templates/skills/application/steps/step-07-tests.md +12 -132
  40. package/templates/skills/business-analyse/SKILL.md +11 -2
  41. package/templates/skills/business-analyse/html/ba-interactive.html +3214 -2246
  42. package/templates/skills/business-analyse/html/build-html.js +77 -0
  43. package/templates/skills/business-analyse/html/src/scripts/01-data-init.js +130 -0
  44. package/templates/skills/business-analyse/html/src/scripts/02-navigation.js +22 -0
  45. package/templates/skills/business-analyse/html/src/scripts/03-render-cadrage.js +208 -0
  46. package/templates/skills/business-analyse/html/src/scripts/04-render-modules.js +211 -0
  47. package/templates/skills/business-analyse/html/src/scripts/05-render-specs.js +554 -0
  48. package/templates/skills/business-analyse/html/src/scripts/06-render-consolidation.js +110 -0
  49. package/templates/skills/business-analyse/html/src/scripts/07-render-handoff.js +90 -0
  50. package/templates/skills/business-analyse/html/src/scripts/08-editing.js +45 -0
  51. package/templates/skills/business-analyse/html/src/scripts/09-export.js +168 -0
  52. package/templates/skills/business-analyse/html/src/scripts/10-comments.js +171 -0
  53. package/templates/skills/business-analyse/html/src/scripts/11-review-panel.js +161 -0
  54. package/templates/skills/business-analyse/html/src/styles/01-variables.css +38 -0
  55. package/templates/skills/business-analyse/html/src/styles/02-layout.css +101 -0
  56. package/templates/skills/business-analyse/html/src/styles/03-navigation.css +62 -0
  57. package/templates/skills/business-analyse/html/src/styles/04-cards.css +196 -0
  58. package/templates/skills/business-analyse/html/src/styles/05-modules.css +325 -0
  59. package/templates/skills/business-analyse/html/src/styles/06-wireframes.css +230 -0
  60. package/templates/skills/business-analyse/html/src/styles/07-comments.css +184 -0
  61. package/templates/skills/business-analyse/html/src/styles/08-review-panel.css +241 -0
  62. package/templates/skills/business-analyse/html/src/template.html +623 -0
  63. package/templates/skills/business-analyse/references/cadrage-structure-cards.md +78 -0
  64. package/templates/skills/business-analyse/references/cadrage-vibe-coding.md +97 -0
  65. package/templates/skills/business-analyse/references/consolidation-structural-checks.md +92 -0
  66. package/templates/skills/business-analyse/references/deploy-data-build.md +121 -0
  67. package/templates/skills/business-analyse/references/deploy-modes.md +49 -0
  68. package/templates/skills/business-analyse/references/handoff-file-templates.md +119 -0
  69. package/templates/skills/business-analyse/references/handoff-mappings.md +81 -0
  70. package/templates/skills/business-analyse/references/html-data-mapping.md +10 -2
  71. package/templates/skills/business-analyse/references/init-schema-deployment.md +65 -0
  72. package/templates/skills/business-analyse/references/review-data-mapping.md +363 -0
  73. package/templates/skills/business-analyse/references/spec-auto-inference.md +57 -0
  74. package/templates/skills/business-analyse/references/ui-dashboard-spec.md +85 -0
  75. package/templates/skills/business-analyse/references/ui-resource-cards.md +110 -0
  76. package/templates/skills/business-analyse/references/validate-incremental-html.md +55 -0
  77. package/templates/skills/business-analyse/steps/step-00-init.md +35 -68
  78. package/templates/skills/business-analyse/steps/step-01-cadrage.md +5 -194
  79. package/templates/skills/business-analyse/steps/step-03a-data.md +6 -49
  80. package/templates/skills/business-analyse/steps/step-03b-ui.md +12 -178
  81. package/templates/skills/business-analyse/steps/step-03d-validate.md +3 -48
  82. package/templates/skills/business-analyse/steps/step-04-consolidation.md +9 -104
  83. package/templates/skills/business-analyse/steps/step-05a-handoff.md +25 -441
  84. package/templates/skills/business-analyse/steps/step-05b-deploy.md +19 -187
  85. package/templates/skills/business-analyse/steps/step-06-review.md +277 -0
  86. package/templates/skills/cc-agent/references/agent-behavior-patterns.md +95 -0
  87. package/templates/skills/cc-agent/steps/step-02-generate.md +5 -78
  88. package/templates/skills/check-version/SKILL.md +7 -0
  89. package/templates/skills/controller/references/controller-code-templates.md +159 -0
  90. package/templates/skills/controller/references/permission-sync-templates.md +152 -0
  91. package/templates/skills/controller/steps/step-03-generate.md +6 -158
  92. package/templates/skills/controller/steps/step-04-perms.md +5 -144
  93. package/templates/skills/debug/SKILL.md +7 -0
  94. package/templates/skills/explore/SKILL.md +6 -0
  95. package/templates/skills/feature-full/SKILL.md +39 -142
  96. package/templates/skills/feature-full/steps/step-01-implementation.md +120 -0
  97. package/templates/skills/gitflow/references/init-config-template.md +135 -0
  98. package/templates/skills/gitflow/references/init-name-normalization.md +103 -0
  99. package/templates/skills/gitflow/references/plan-template.md +69 -0
  100. package/templates/skills/gitflow/references/start-efcore-preflight.md +70 -0
  101. package/templates/skills/gitflow/references/start-local-config.md +110 -0
  102. package/templates/skills/gitflow/steps/step-init.md +18 -289
  103. package/templates/skills/gitflow/steps/step-plan.md +6 -63
  104. package/templates/skills/gitflow/steps/step-start.md +16 -126
  105. package/templates/skills/mcp/SKILL.md +9 -213
  106. package/templates/skills/mcp/steps/step-01-healthcheck.md +108 -0
  107. package/templates/skills/mcp/steps/step-02-tools.md +73 -0
  108. package/templates/skills/notification/SKILL.md +7 -0
  109. package/templates/skills/quick-search/SKILL.md +5 -0
  110. package/templates/skills/ralph-loop/SKILL.md +99 -381
  111. package/templates/skills/ralph-loop/references/category-rules.md +259 -0
  112. package/templates/skills/ralph-loop/references/compact-loop.md +182 -0
  113. package/templates/skills/ralph-loop/references/task-transform-legacy.md +259 -0
  114. package/templates/skills/ralph-loop/references/team-orchestration.md +189 -0
  115. package/templates/skills/ralph-loop/steps/step-00-init.md +111 -383
  116. package/templates/skills/ralph-loop/steps/step-01-task.md +79 -896
  117. package/templates/skills/ralph-loop/steps/step-02-execute.md +68 -680
  118. package/templates/skills/ralph-loop/steps/step-03-commit.md +47 -277
  119. package/templates/skills/ralph-loop/steps/step-04-check.md +124 -607
  120. package/templates/skills/ralph-loop/steps/step-05-report.md +68 -367
  121. package/templates/skills/refactor/SKILL.md +12 -176
  122. package/templates/skills/refactor/steps/step-01-discover.md +60 -0
  123. package/templates/skills/refactor/steps/step-02-execute.md +67 -0
  124. package/templates/skills/review-code/SKILL.md +19 -257
  125. package/templates/skills/review-code/steps/step-01-smartstack.md +96 -0
  126. package/templates/skills/review-code/steps/step-02-detailed-review.md +80 -0
  127. package/templates/skills/review-code/steps/step-03-react.md +44 -0
  128. package/templates/skills/ui-components/SKILL.md +7 -0
  129. package/templates/skills/utils/SKILL.md +6 -0
  130. package/templates/skills/validate/SKILL.md +6 -0
  131. package/templates/skills/validate-feature/SKILL.md +8 -0
  132. package/templates/skills/workflow/SKILL.md +40 -118
  133. package/templates/skills/workflow/steps/step-01-implementation.md +84 -0
@@ -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,134 @@
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, 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 SeedPermissionsAsync(ICoreDbContext context, CancellationToken ct)
79
+ {
80
+ // Check idempotence
81
+ var exists = await context.Permissions
82
+ .AnyAsync(p => p.Path == "{full_path}.*", ct);
83
+ if (exists) return;
84
+
85
+ // Retrieve modules by Code for FK resolution
86
+ // Use data from {Module}PermissionSeedData.cs
87
+ // Create via Permission.CreateForModule(...) and Permission.CreateWildcard(...)
88
+ // ...
89
+ await ((DbContext)context).SaveChangesAsync(ct);
90
+ }
91
+
92
+ public async Task SeedRolePermissionsAsync(ICoreDbContext context, CancellationToken ct)
93
+ {
94
+ // Check idempotence
95
+ var exists = await context.RolePermissions
96
+ .AnyAsync(rp => rp.Permission!.Path.StartsWith("{full_path}."), ct);
97
+ if (exists) return;
98
+
99
+ // Retrieve existing roles and created permissions
100
+ // Use data from {Module}RolePermissionSeedData.cs
101
+ // Create via RolePermission.Create(roleId, permissionId, "system")
102
+ // ...
103
+ await ((DbContext)context).SaveChangesAsync(ct);
104
+ }
105
+
106
+ // Private helper methods fed by SeedData classes
107
+ // ...
108
+ }
109
+ ```
110
+
111
+ ---
112
+
113
+ ## DI Registration
114
+
115
+ Modify `Infrastructure/DependencyInjection.cs` of the client project:
116
+
117
+ ```csharp
118
+ // Add using:
119
+ using SmartStack.Application.Common.Interfaces;
120
+
121
+ // In the registration method:
122
+ services.AddScoped<IClientSeedDataProvider, {AppPascalName}SeedDataProvider>();
123
+ ```
124
+
125
+ ---
126
+
127
+ ## Critical Rules
128
+
129
+ 1. **Factory methods mandatory**: `NavigationModule.Create(...)`, `Permission.CreateForModule(...)`, `RolePermission.Create(...)` — NEVER `new Entity()`
130
+ 2. **Idempotence**: Each Seed method checks existence before inserting
131
+ 3. **SaveChangesAsync per group**: Navigation → save → Permissions → save → RolePermissions → save
132
+ 4. **Deterministic GUIDs**: Use IDs from SeedData classes (not `Guid.NewGuid()`)
133
+ 5. **Resolve FK by Code**: Parent modules are found by `Code`, not hardcoded GUID
134
+ 6. **Order property**: Use `100` as default. If multiple providers exist, they run in Order sequence
@@ -0,0 +1,73 @@
1
+ # Frontend Test Infrastructure & Generation
2
+
3
+ > Reference for step-07-tests.md — Vitest + Testing Library + MSW setup and component test generation.
4
+
5
+ ## 1. Check Frontend Test Infrastructure
6
+
7
+ Verify that the frontend project has Vitest + Testing Library configured:
8
+
9
+ ```bash
10
+ # Check if vitest.config.ts exists in the web/frontend project
11
+ ls {WebProjectPath}/vitest.config.ts 2>/dev/null
12
+ ```
13
+
14
+ If NOT found, deploy the test infrastructure:
15
+
16
+ ### Install packages
17
+
18
+ ```bash
19
+ cd {WebProjectPath}
20
+ npm install -D vitest @testing-library/react @testing-library/jest-dom @testing-library/user-event jsdom msw
21
+ ```
22
+
23
+ ### Copy infrastructure files from SmartStack templates
24
+
25
+ | Template Source | Destination |
26
+ |----------------|-------------|
27
+ | `templates/project/test-frontend/vitest.config.ts` | `{WebProjectPath}/vitest.config.ts` |
28
+ | `templates/project/test-frontend/setup.ts` | `{WebProjectPath}/src/test/setup.ts` |
29
+ | `templates/project/test-frontend/test-utils.tsx` | `{WebProjectPath}/src/test/test-utils.tsx` |
30
+ | `templates/project/test-frontend/msw/server.ts` | `{WebProjectPath}/src/test/msw/server.ts` |
31
+ | `templates/project/test-frontend/msw/handlers.ts` | `{WebProjectPath}/src/test/msw/handlers.ts` |
32
+
33
+ ### Add test scripts to `package.json` (if missing)
34
+
35
+ ```json
36
+ {
37
+ "scripts": {
38
+ "test": "vitest run",
39
+ "test:watch": "vitest",
40
+ "test:coverage": "vitest run --coverage"
41
+ }
42
+ }
43
+ ```
44
+
45
+ ## 2. Generate Frontend Tests
46
+
47
+ ```
48
+ Tool: mcp__smartstack__scaffold_frontend_tests
49
+ Args:
50
+ name: "{entity_name}"
51
+ components: ["all"]
52
+ apiRoute: "/api/{entity_code}"
53
+ ```
54
+
55
+ This generates:
56
+ - `src/pages/{context}/{application}/__tests__/{EntityName}Page.test.tsx` - Page rendering, loading, error states
57
+ - `src/pages/{context}/{application}/__tests__/{EntityName}ListView.test.tsx` - List display, pagination, view toggle
58
+ - `src/pages/{context}/{application}/__tests__/{EntityName}DetailPage.test.tsx` - Detail view, tabs, back navigation
59
+ - `src/hooks/__tests__/use{EntityName}Preferences.test.ts` - Preference get/set
60
+ - `src/services/api/__tests__/{entityName}Api.test.ts` - API client calls with MSW
61
+
62
+ ## 3. Run Frontend Tests (BLOCKING)
63
+
64
+ ```bash
65
+ cd {WebProjectPath}
66
+ npx vitest run --reporter=default
67
+ ```
68
+
69
+ **ALL frontend tests MUST pass.** If tests fail:
70
+ 1. Read the failure output carefully
71
+ 2. Fix the failing tests or the components they test
72
+ 3. Re-run until all tests pass
73
+ 4. Do NOT proceed to the next step until all tests are green
@@ -0,0 +1,72 @@
1
+ # Test Infrastructure Prerequisites
2
+
3
+ > Reference for step-07-tests.md — verify and scaffold test project before generating tests.
4
+
5
+ ## 1. Verify Test Project Exists
6
+
7
+ ```bash
8
+ # Look for existing test project
9
+ ls *Tests*/*.csproj 2>/dev/null || ls tests/*/*.csproj 2>/dev/null
10
+ ```
11
+
12
+ If NO test project exists, create one:
13
+
14
+ ```bash
15
+ dotnet new xunit -n {SolutionName}.Tests -o tests/{SolutionName}.Tests
16
+ dotnet sln add tests/{SolutionName}.Tests/{SolutionName}.Tests.csproj
17
+ ```
18
+
19
+ ## 2. Required NuGet Packages
20
+
21
+ | Package | Purpose |
22
+ |---------|---------|
23
+ | `xunit` | Test framework |
24
+ | `FluentAssertions` | Assertion library |
25
+ | `Moq` | Mocking framework |
26
+ | `Microsoft.AspNetCore.Mvc.Testing` | Integration test support |
27
+ | `Microsoft.EntityFrameworkCore.Sqlite` | SQLite in-memory for REAL integration tests |
28
+ | `Microsoft.Data.Sqlite` | SQLite connection support |
29
+ | `Microsoft.EntityFrameworkCore.InMemory` | In-memory DB for repository tests |
30
+ | `FluentValidation.TestHelper` | Validator testing support |
31
+
32
+ ```bash
33
+ cd tests/{SolutionName}.Tests
34
+ dotnet add package FluentAssertions
35
+ dotnet add package Moq
36
+ dotnet add package Microsoft.AspNetCore.Mvc.Testing
37
+ dotnet add package Microsoft.EntityFrameworkCore.Sqlite
38
+ dotnet add package Microsoft.Data.Sqlite
39
+ dotnet add package Microsoft.EntityFrameworkCore.InMemory
40
+ dotnet add package FluentValidation.TestHelper
41
+ ```
42
+
43
+ ## 3. Project References
44
+
45
+ The test project MUST reference the API project (for WebApplicationFactory):
46
+
47
+ ```bash
48
+ cd tests/{SolutionName}.Tests
49
+ dotnet add reference ../../src/{SolutionName}.Api/{SolutionName}.Api.csproj
50
+ dotnet add reference ../../src/{SolutionName}.Application/{SolutionName}.Application.csproj
51
+ dotnet add reference ../../src/{SolutionName}.Domain/{SolutionName}.Domain.csproj
52
+ dotnet add reference ../../src/{SolutionName}.Infrastructure/{SolutionName}.Infrastructure.csproj
53
+ ```
54
+
55
+ ## 4. Program.cs Accessibility (BLOCKING)
56
+
57
+ The API project's `Program` class must be accessible for `WebApplicationFactory<Program>`.
58
+
59
+ Check if `Program.cs` ends with `public partial class Program { }`. If not, add it:
60
+
61
+ ```csharp
62
+ // At the very end of Program.cs
63
+ public partial class Program { }
64
+ ```
65
+
66
+ **Alternatively**, add to the API `.csproj`:
67
+
68
+ ```xml
69
+ <ItemGroup>
70
+ <InternalsVisibleTo Include="{SolutionName}.Tests" />
71
+ </ItemGroup>
72
+ ```
@@ -138,204 +138,13 @@ The SeedData files will be consumed by the `IClientSeedDataProvider` generated a
138
138
 
139
139
  ## FALLBACK PROCEDURE (When MCP Unavailable)
140
140
 
141
- > This procedure generates navigation seeds following SmartStack.app patterns.
142
- > Reference: `templates-seed.md` for code templates.
143
- >
144
- > **Branch by Project Type:**
145
- > - If `{seeding_strategy}` = "hasdata" (core project): Follow F1-F8 below (existing pattern)
146
- > - If `{seeding_strategy}` = "provider" (client project): Follow **CLIENT PROJECT HANDLING** above (create SeedData classes only, no HasData)
147
-
148
- ### F1. Read Existing Configuration Files
149
-
150
- **CRITICAL:** Before generating any code, read existing files to determine state:
151
-
152
- 1. **Find the Navigation Configuration directory:**
153
- ```
154
- Glob: **/Persistence/Configurations/Navigation/Navigation*Configuration.cs
155
- ```
156
-
157
- 2. **Read NavigationTranslationConfiguration.cs** - Find the last GUID index:
158
- ```
159
- Search for: the last call to GenerateGuid(index++)
160
- The index variable starts at 1 and increments per translation entry.
161
- Your new translations MUST continue from the next index value.
162
- ```
163
-
164
- 3. **Read Navigation{Level}Configuration.cs** - Check existing entities:
165
- ```
166
- Read the Configuration for the target level (Context, Application, Module, Section).
167
- Check if it already references a SeedData class: builder.HasData(Navigation{Level}SeedData.GetSeedData())
168
- If yes: Read the corresponding SeedData class to find existing entries.
169
- If no: You will need to add HasData() call.
170
- ```
171
-
172
- 4. **Read existing SeedData files** (if they exist):
173
- ```
174
- Glob: **/Seeding/Data/Navigation/Navigation{Level}SeedData.cs
175
- Check for existing entity IDs to avoid collisions.
176
- ```
177
-
178
- ### F2. Determine Parent GUID
179
-
180
- For non-context levels, find the parent entity GUID:
181
-
182
- | Level | Parent | Where to Find Parent GUID |
183
- |-------|--------|---------------------------|
184
- | application | context | `NavigationContextSeedData.cs` → e.g. `PlatformContextId` |
185
- | module | application | `NavigationApplicationSeedData.cs` → e.g. `AdministrationAppId` |
186
- | section | module | `NavigationModuleSeedData.cs` → e.g. `UsersModuleId` |
187
-
188
- Read the parent SeedData class and find the GUID matching `{parent_path}`.
189
-
190
- ### F3. Generate Navigation Entity GUID
191
-
192
- Generate a deterministic GUID for the new navigation entity:
193
-
194
- ```csharp
195
- // Use SHA256 hash of the full_path for deterministic generation
196
- using var sha256 = System.Security.Cryptography.SHA256.Create();
197
- var hash = sha256.ComputeHash(Encoding.UTF8.GetBytes("navigation-{level}-{full_path}"));
198
- var guid = new Guid(hash.Take(16).ToArray());
199
- ```
200
-
201
- **Rules:**
202
- - NEVER use `Guid.NewGuid()`
203
- - Read existing SeedData GUIDs to verify no collision
204
- - Store result as `{navigation_guid}`
205
-
206
- ### F4. Write Navigation Entity Seed
207
-
208
- Based on `{level}`, write the seed entry.
209
-
210
- **Option A: Project uses SeedData classes (SmartStack.app pattern)**
211
-
212
- If `Navigation{Level}SeedData.cs` exists, add the new entity:
213
-
214
- ```csharp
215
- // In Infrastructure/Persistence/Seeding/Data/Navigation/Navigation{Level}SeedData.cs
216
-
217
- // Add static GUID field
218
- public static readonly Guid {PascalCode}Id = Guid.Parse("{navigation_guid}");
219
-
220
- // Add to GetSeedData() return array
221
- new {
222
- Id = {PascalCode}Id,
223
- ParentFk = Navigation{ParentLevel}SeedData.{ParentPascalCode}Id, // FK varies by level
224
- Code = "{code}",
225
- Label = "{labels.en}",
226
- Description = "{descriptions.en}",
227
- Icon = "{icon}",
228
- IconType = IconType.Lucide,
229
- Route = "/{full_path_with_slashes}",
230
- DisplayOrder = {display_order},
231
- IsActive = true,
232
- CreatedAt = SeedConstants.SeedDate
233
- }
234
- ```
235
-
236
- **FK property by level:**
237
-
238
- | Level | FK Property | References |
239
- |-------|-------------|------------|
240
- | context | (none) | - |
241
- | application | `ContextId` | NavigationContextSeedData.{Parent}Id |
242
- | module | `ApplicationId` | NavigationApplicationSeedData.{Parent}Id |
243
- | section | `ModuleId` | NavigationModuleSeedData.{Parent}Id |
244
-
245
- **Option B: Project uses inline HasData**
246
-
247
- If no SeedData class exists, add directly to `Navigation{Level}Configuration.cs`:
248
-
249
- ```csharp
250
- // In Configure method, add:
251
- builder.HasData(new {
252
- Id = Guid.Parse("{navigation_guid}"),
253
- // ... same properties as Option A
254
- });
255
- ```
256
-
257
- ### F5. Write Translation Entries
258
-
259
- Add 4 translation entries to `NavigationTranslationConfiguration.cs`:
260
-
261
- 1. Read the file to find the current highest `index` value
262
- 2. Continue from `index + 1`
263
- 3. Use the SAME `GenerateGuid` method already defined in the file:
264
-
265
- ```csharp
266
- // In GetSeedData() method, add at the end before return:
267
-
268
- // {level}: {code} translations
269
- translations.Add(new {
270
- Id = GenerateGuid(index++),
271
- EntityType = NavigationEntityType.{Level},
272
- EntityId = Navigation{Level}SeedData.{PascalCode}Id, // or Guid.Parse("{navigation_guid}")
273
- LanguageCode = "fr",
274
- Label = "{labels.fr}",
275
- Description = "{descriptions.fr}",
276
- CreatedAt = seedDate
277
- });
278
- translations.Add(new {
279
- Id = GenerateGuid(index++),
280
- EntityType = NavigationEntityType.{Level},
281
- EntityId = Navigation{Level}SeedData.{PascalCode}Id,
282
- LanguageCode = "en",
283
- Label = "{labels.en}",
284
- Description = "{descriptions.en}",
285
- CreatedAt = seedDate
286
- });
287
- translations.Add(new {
288
- Id = GenerateGuid(index++),
289
- EntityType = NavigationEntityType.{Level},
290
- EntityId = Navigation{Level}SeedData.{PascalCode}Id,
291
- LanguageCode = "it",
292
- Label = "{labels.it}",
293
- Description = "{descriptions.it}",
294
- CreatedAt = seedDate
295
- });
296
- translations.Add(new {
297
- Id = GenerateGuid(index++),
298
- EntityType = NavigationEntityType.{Level},
299
- EntityId = Navigation{Level}SeedData.{PascalCode}Id,
300
- LanguageCode = "de",
301
- Label = "{labels.de}",
302
- Description = "{descriptions.de}",
303
- CreatedAt = seedDate
304
- });
305
- ```
306
-
307
- ### F6. Store Result
308
-
309
- ```
310
- {navigation_guid} = [generated GUID]
311
- {seed_method} = "fallback" // Indicates MCP was not used
312
- ```
313
-
314
- ### F7. Validation Checklist
315
-
316
- Before proceeding, verify:
317
- - [ ] Deterministic GUID generated (not NewGuid())
318
- - [ ] 4 languages present (fr, en, it, de)
319
- - [ ] Translation index continues existing sequence (no gaps, no collisions)
320
- - [ ] Parent GUID correctly references existing entity
321
- - [ ] Route path matches `/{context}/{app}/{module}` pattern
322
- - [ ] DisplayOrder is consistent with existing entities
323
- - [ ] Code is WRITTEN to files, not just displayed
324
-
325
- ### F8. Present Summary
326
-
327
- ```markdown
328
- ## Navigation Seeds Generated (Fallback)
329
-
330
- **Entity:** {level} - {code}
331
- **GUID:** {navigation_guid}
332
- **Path:** {full_path}
333
-
334
- ### Files Updated
335
-
336
- 1. **Navigation{Level}SeedData.cs** (or Configuration.cs) - New entity entry
337
- 2. **NavigationTranslationConfiguration.cs** - 4 translation entries added
338
- ```
141
+ See [references/nav-fallback-procedure.md](../references/nav-fallback-procedure.md) for the complete 8-step fallback:
142
+ - **F1:** Read existing Configuration/SeedData files to determine state
143
+ - **F2:** Determine parent GUID by level
144
+ - **F3:** Generate deterministic GUID (SHA256, never NewGuid())
145
+ - **F4:** Write navigation entity seed (SeedData class or inline HasData)
146
+ - **F5:** Write 4 translation entries (continue existing index sequence)
147
+ - **F6-F8:** Store result, validation checklist, summary
339
148
 
340
149
  ---
341
150